可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want the user to be able to put the cell into editing mode and highlight the row the cell is contained in with a single click. By default, this is double click. How do I override or implement this? I've searched on google, and the codeplex answer doesn't work for me.
I'm pretty new to WPF and coding in general, so a simple answer is better.
回答1:
Here is how I resolved this issue:
This DataGrid is bound to a CollectionViewSource (Containing dummy Person objects).
The magic happens there : DataGridCell.Selected="DataGrid_GotFocus".
I simply hook the Selected Event of the DataGrid cell, and call BeginEdit() on the DataGrid.
Here is the code behind for the event handler :
private void DataGrid_GotFocus(object sender, RoutedEventArgs e) { // Lookup for the source to be DataGridCell if (e.OriginalSource.GetType() == typeof(DataGridCell)) { // Starts the Edit on the row; DataGrid grd = (DataGrid)sender; grd.BeginEdit(e); } }
{enjoy}
回答2:
The answer from Micael Bergeron was a good start for me to find a solution thats working for me. To allow single-click editing also for Cells in the same row thats already in edit mode i had to adjust it a bit. Using SelectionUnit Cell was no option for me.
Instead of using the DataGridCell.Selected Event which is only fired for the first time a row's cell is clicked, i used the DataGridCell.GotFocus Event.
If you do so you will have always the correct cell focused and in edit mode, but no control in the cell will be focused, this i solved like this
private void DataGrid_CellGotFocus(object sender, RoutedEventArgs e) { // Lookup for the source to be DataGridCell if (e.OriginalSource.GetType() == typeof(DataGridCell)) { // Starts the Edit on the row; DataGrid grd = (DataGrid)sender; grd.BeginEdit(e); Control control = GetFirstChildByType(e.OriginalSource as DataGridCell); if (control != null) { control.Focus(); } } } private T GetFirstChildByType(DependencyObject prop) where T : DependencyObject { for (int i = 0; i (child); if (castedProp != null) return castedProp; } return null; }
回答3:
From: http://wpf.codeplex.com/wikipage?title=Single-Click%20Editing
XAML:
CODE-BEHIND:
// // SINGLE CLICK EDITING // private void DataGridCell_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { DataGridCell cell = sender as DataGridCell; if (cell != null && !cell.IsEditing && !cell.IsReadOnly) { if (!cell.IsFocused) { cell.Focus(); } DataGrid dataGrid = FindVisualParent(cell); if (dataGrid != null) { if (dataGrid.SelectionUnit != DataGridSelectionUnit.FullRow) { if (!cell.IsSelected) cell.IsSelected = true; } else { DataGridRow row = FindVisualParent(cell); if (row != null && !row.IsSelected) { row.IsSelected = true; } } } } } static T FindVisualParent(UIElement element) where T : UIElement { UIElement parent = element; while (parent != null) { T correctlyTyped = parent as T; if (correctlyTyped != null) { return correctlyTyped; } parent = VisualTreeHelper.GetParent(parent) as UIElement; } return null; }
回答4:
The solution from http://wpf.codeplex.com/wikipage?title=Single-Click%20Editing worked great for me, but I enabled it for every DataGrid using a Style defined in a ResourceDictionary. To use handlers in resource dictionaries you need to add a code-behind file to it. Here's how you do it:
This is a DataGridStyles.xaml Resource Dictionary:
Note the x:Class attribute in the root element. Create a class file. In this example it'd be DataGridStyles.xaml.cs. Put this code inside:
using System.Windows.Controls; using System.Windows; using System.Windows.Input; namespace YourNamespace { partial class DataGridStyles : ResourceDictionary { public DataGridStyles() { InitializeComponent(); } // The code from the myermian's answer goes here. }
回答5:
回答6:
There are two issues with user2134678's answer. One is very minor and has no functional effect. The other is fairly significant.
The first issueis that the GotFocus is actually being called against the DataGrid, not the DataGridCell in practice. The DataGridCell qualifier in the XAML is redundant.
The main problem I found with the answer is that the Enter key behavior is broken. Enter should move you to the next cell below the current cell in normal DataGrid behavior. However, what actually happens behind the scenes is GotFocus event will be called twice. Once upon the current cell losing focus, and once upon the new cell gaining focus. But as long as BeginEdit is called on that first cell, the next cell will never be activated. The upshot is that you have one-click editing, but anyone who isn't literally clicking on the grid is going to be inconvenienced, and a user-interface designer should not assume that all users are using mouses. (Keyboard users can sort of get around it by using Tab, but that still means they're jumping through hoops that they shouldn't need to.)
So the solution to this problem? Handle event KeyDown for the cell and if the Key is the Enter key, set a flag that stops BeginEdit from firing on the first cell. Now the Enter key behaves as it should.
To begin with, add the following Style to your DataGrid:
Apply that style to "CellStyle" property the columns for which you want to enable one-click.
Then in the code behind you have the following in your GotFocus handler (note that I'm using VB here because that's what our "one-click data grid requesting" client wanted as the development language):
Private _endEditing As Boolean = False Private Sub DataGrid_GotFocus(ByVal sender As Object, ByVal e As RoutedEventArgs) If Me._endEditing Then Me._endEditing = False Return End If Dim cell = TryCast(e.OriginalSource, DataGridCell) If cell Is Nothing Then Return End If If cell.IsReadOnly Then Return End If DirectCast(sender, DataGrid).BeginEdit(e) . . .
Then you add your handler for the KeyDown event:
Private Sub DataGridCell_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) If e.Key = Key.Enter Then Me._endEditing = True End If End Sub
Now you have a DataGrid that hasn't changed any fundamental behavior of the out-of-the-box implementation and yet supports single-click editing.
回答7:
I solved it by adding a trigger that sets IsEditing property of the DataGridCell to True when the mouse is over it. It solved most of my problems. It works with comboboxes too.
回答8:
public void ReachThisMethod(object sender) { ((System.Windows.Controls.DataGridCell)(sender)).IsEditing = true; }