在WPF DataGrid中单击编辑

Aus*_*tin 87 .net c# wpf events xaml

我希望用户能够将单元格置于编辑模式,并通过单击突出显示包含单元格的行.默认情况下,这是双击.

如何覆盖或实现此功能?

Mic*_*ron 72

以下是我解决此问题的方法:

<DataGrid DataGridCell.Selected="DataGrid_GotFocus" 
          ItemsSource="{Binding Source={StaticResource itemView}}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Nom" Binding="{Binding Path=Name}"/>
        <DataGridTextColumn Header="Age" Binding="{Binding Path=Age}"/>
    </DataGrid.Columns>
</DataGrid>
Run Code Online (Sandbox Code Playgroud)

此DataGrid绑定到CollectionViewSource(包含虚拟Person对象).

魔术发生在那里:DataGridCell.Selected ="DataGrid_GotFocus".

我只是挂钩DataGrid单元格的Selected Event,并在DataGrid上调用BeginEdit().

以下是事件处理程序的代码:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 通过将DataGrid上的`SelectionUnit`属性设置为`Cell`,可以解决已经选择的行问题. (6认同)
  • 这很好用,但我不建议这样做.我在我的项目中使用了这个,并决定回滚到标准的DG行为.将来,当您的DG增长并变得复杂时,您将遇到验证问题,添加新行和其他奇怪的行为. (4认同)

小智 39

Micael Bergeron的答案是我找到适合我的解决方案的良好开端.为了允许对已经处于编辑模式的同一行中的单元格进行单击编辑,我必须稍微调整一下.使用SelectionUnit Cell对我来说不是一个选择.

而不是使用仅在第一次单击行的单元格时触发的DataGridCell.Selected事件,而是使用DataGridCell.GotFocus事件.

<DataGrid DataGridCell.GotFocus="DataGrid_CellGotFocus" />
Run Code Online (Sandbox Code Playgroud)

如果你这样做,你将始终拥有正确的细胞聚焦和编辑模式,但细胞中的控制将无法集中,这我解决了这样

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<Control>(e.OriginalSource as DataGridCell);
        if (control != null)
        {
            control.Focus();
        }
    }
}

private T GetFirstChildByType<T>(DependencyObject prop) where T : DependencyObject
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(prop); i++)
    {
        DependencyObject child = VisualTreeHelper.GetChild((prop), i) as DependencyObject;
        if (child == null)
            continue;

        T castedProp = child as T;
        if (castedProp != null)
            return castedProp;

        castedProp = GetFirstChildByType<T>(child);

        if (castedProp != null)
            return castedProp;
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

  • 复选框似乎不适合我?我仍然需要双击他们 (3认同)

m-y*_*m-y 8

来自:http://wpf.codeplex.com/wikipage?title = Single-Click%20Editing

XAML:

<!-- SINGLE CLICK EDITING -->
<Style TargetType="{x:Type dg:DataGridCell}">
    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridCell_PreviewMouseLeftButtonDown"></EventSetter>
</Style>
Run Code Online (Sandbox Code Playgroud)

后台代码:

//
// 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<DataGrid>(cell);
        if (dataGrid != null)
        {
            if (dataGrid.SelectionUnit != DataGridSelectionUnit.FullRow)
            {
                if (!cell.IsSelected)
                    cell.IsSelected = true;
            }
            else
            {
                DataGridRow row = FindVisualParent<DataGridRow>(cell);
                if (row != null && !row.IsSelected)
                {
                    row.IsSelected = true;
                }
            }
        }
    }
}

static T FindVisualParent<T>(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;
}
Run Code Online (Sandbox Code Playgroud)


And*_*kki 6

来自http://wpf.codeplex.com/wikipage?title=Single-Click%20Editing的解决方案对我来说很有用,但是我使用ResourceDictionary中定义的Style为每个DataGrid启用了它.要在资源字典中使用处理程序,您需要向其添加代码隐藏文件.这是你如何做到的:

这是一个DataGridStyles.xaml资源字典:

<ResourceDictionary x:Class="YourNamespace.DataGridStyles"
            x:ClassModifier="public"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="DataGrid">
        <!-- Your DataGrid style definition goes here -->

        <!-- Cell style -->
        <Setter Property="CellStyle">
            <Setter.Value>
                <Style TargetType="DataGridCell">                    
                    <!-- Your DataGrid Cell style definition goes here -->
                    <!-- Single Click Editing -->
                    <EventSetter Event="PreviewMouseLeftButtonDown"
                             Handler="DataGridCell_PreviewMouseLeftButtonDown" />
                </Style>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)

请注意根元素中的x:Class属性.创建一个类文件.在这个例子中,它是DataGridStyles.xaml.cs.将此代码放入:

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.
}
Run Code Online (Sandbox Code Playgroud)


小智 6

我通过添加一个触发器来解决这个问题,当鼠标悬停在 DataGridCell 上时,该触发器将 DataGridCell 的 IsEditing 属性设置为 True。它解决了我的大部分问题。它也适用于组合框。

<Style TargetType="DataGridCell">
     <Style.Triggers>
         <Trigger Property="IsMouseOver" Value="True">
             <Setter Property="IsEditing" Value="True" />
         </Trigger>
     </Style.Triggers>
 </Style>
Run Code Online (Sandbox Code Playgroud)


小智 5

我更喜欢这种基于 Dušan Kneževi 的方式?建议。你点击一个就是这样))

<DataGrid.Resources>

    <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
        <Style.Triggers>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsMouseOver"
                                   Value="True" />
                        <Condition Property="IsReadOnly"
                                   Value="False" />
                    </MultiTrigger.Conditions>
                    <MultiTrigger.Setters>
                        <Setter Property="IsEditing"
                                Value="True" />
                    </MultiTrigger.Setters>
                </MultiTrigger>
        </Style.Triggers>
    </Style>

</DataGrid.Resources>
Run Code Online (Sandbox Code Playgroud)