1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-05-31 22:41:37 +00:00

Add double-click handler

Doesn't really do anything yet.  The hard part in WPF is figuring
out which row and column were clicked.
This commit is contained in:
Andy McFadden 2019-06-11 18:45:08 -07:00
parent 1a9f99098a
commit b45382d294
4 changed files with 96 additions and 5 deletions

View File

@ -17,6 +17,8 @@ using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
namespace CommonWPF {
@ -54,8 +56,11 @@ namespace CommonWPF {
}
/// <summary>
/// Add functions to get the element that's currently shown at the top of the ListView
/// window, and to scroll the list so that a specific item is at the top.
/// Helper functions for working with a ListView.
///
/// ListViews are generalized to an absurd degree, so simple things like "what column did
/// I click on" and "what row is at the top" that were easy in WinForms are not provided
/// by WPF.
/// </summary>
public static class ListViewExtensions {
/// <summary>
@ -93,5 +98,55 @@ namespace CommonWPF {
sv.ScrollToBottom();
lv.ScrollIntoView(item);
}
/// <summary>
/// Returns the ListViewItem that was clicked on, or null if an LVI wasn't the target
/// of a click (e.g. off the bottom of the list).
/// </summary>
public static ListViewItem GetClickedItem(this ListView lv, MouseButtonEventArgs e) {
DependencyObject dep = (DependencyObject)e.OriginalSource;
// Should start at something like a TextBlock. Walk up the tree until we hit the
// ListViewItem.
while (dep != null && !(dep is ListViewItem)) {
dep = VisualTreeHelper.GetParent(dep);
}
if (dep == null) {
return null;
}
return (ListViewItem)dep;
}
/// <summary>
/// Determines which column was the target of a mouse click. Only works for ListView
/// with GridView.
/// </summary>
/// <remarks>
/// There's just no other way to do this with ListView. With DataGrid you can do this
/// somewhat reasonably
/// (https://blog.scottlogic.com/2008/12/02/wpf-datagrid-detecting-clicked-cell-and-row.html),
/// but ListView just doesn't want to help.
/// </remarks>
/// <returns>Column index, or -1 if the click was outside the columns (e.g. off the right
/// edge).</returns>
public static int GetClickEventColumn(this ListView lv, MouseButtonEventArgs e) {
// There's a bit of padding that seems to offset things. Not sure how to account
// for it, so for now just fudge it.
const int FUDGE = 4;
Point p = e.GetPosition(lv);
GridView gv = (GridView)lv.View;
double startPos = FUDGE;
for (int index = 0; index < gv.Columns.Count; index++) {
GridViewColumn col = gv.Columns[index];
if (p.X < startPos + col.ActualWidth) {
return index;
}
startPos += col.ActualWidth;
}
return -1;
}
}
}

View File

@ -637,6 +637,10 @@ namespace SourceGenWPF {
#region Main window UI event handlers
public void HandleDoubleClick(int row, int col) {
Debug.WriteLine("DCLICK: row=" + row + " col=" + col);
}
public void OpenRecentProject(int projIndex) {
if (!CloseProject()) {
return;

View File

@ -23,7 +23,8 @@ limitations under the License.
Title="6502bench SourceGen"
Icon="/SourceGenWPF;component/Res/SourceGenIcon.ico"
Width="1000" Height="600" MinWidth="800" MinHeight="500"
Loaded="Window_Loaded">
Loaded="Window_Loaded"
MouseDown="Window_MouseDown">
<Window.Resources>
<ResourceDictionary>
@ -305,7 +306,8 @@ limitations under the License.
Visibility="{Binding Path=CodeListVisibility}"
VirtualizingStackPanel.VirtualizationMode="Recycling"
ItemContainerStyle="{StaticResource codeListItemStyle}"
SelectionChanged="CodeListView_SelectionChanged">
SelectionChanged="CodeListView_SelectionChanged"
MouseDoubleClick="CodeListView_MouseDoubleClick">
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridViewColumn Header="Offset" DisplayMemberBinding="{Binding Offset}"/>

View File

@ -75,6 +75,7 @@ namespace SourceGenWPF.ProjWin {
CodeDisplayList = new DisplayList();
codeListView.ItemsSource = CodeDisplayList;
// https://dlaa.me/blog/post/9425496 to re-auto-size after data added
mMainCtrl = new MainController(this);
@ -211,6 +212,36 @@ namespace SourceGenWPF.ProjWin {
get { return mShowCodeListView ? Visibility.Visible : Visibility.Hidden; }
}
/// <summary>
/// Catch mouse-down events so we can treat the fourth mouse button as "back".
/// </summary>
private void Window_MouseDown(object sender, MouseButtonEventArgs e) {
if (e.ChangedButton == MouseButton.XButton1) {
Debug.WriteLine("TODO: navigate back");
}
}
/// <summary>
/// Handles a double-click on the code list. We have to figure out which row and
/// column were clicked, which is not easy in WPF.
/// </summary>
private void CodeListView_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
Debug.Assert(sender == codeListView);
ListViewItem lvi = codeListView.GetClickedItem(e);
if (lvi == null) {
return;
}
DisplayList.FormattedParts parts = (DisplayList.FormattedParts)lvi.Content;
int row = parts.ListIndex;
int col = codeListView.GetClickEventColumn(e);
if (col < 0) {
return;
}
mMainCtrl.HandleDoubleClick(row, col);
}
#region Selection management
private void CodeListView_SelectionChanged(object sender, SelectionChangedEventArgs e) {
@ -526,6 +557,5 @@ namespace SourceGenWPF.ProjWin {
new ObservableCollection<ReferencesListItem>();
#endregion References panel
}
}