【问题标题】:Create custom edit row in DataGrid wpf在 DataGrid wpf 中创建自定义编辑行
【发布时间】:2016-01-25 08:29:03
【问题描述】:

默认情况下,双击一个单元格会使其进入编辑模式,当它失去焦点时,如果我们按下ESC,它将提交数据或回滚。

我想创建一个自定义按钮来将一行中的所有单元格切换到编辑模式、一个提交更改的按钮和一个取消更改的按钮。

Datagrid 是否已经支持此功能,还是我必须自己实现所有逻辑?

我找到了一种将一行的所有单元格切换到编辑模式的方法,但是每次文本框失去焦点时,它都会关闭编辑模式

如何防止这种情况发生?以及如何使确定按钮提交所有数据?

【问题讨论】:

    标签: c# wpf datagrid


    【解决方案1】:

    使用DataGrid.BeginEdit()/CancelEdit()/CommitEdit() 方法。

    有一些关于编辑的事件需要处理:BeginningEditCellEditEndingPreparingCellForEdit

    使用DataGridCell.IsEditing 属性打开/关闭编辑模式。

    您可以获得DataGridRow,您可以从中循环访问它的DataGridCells。这方面有很多教程。

    满足您特定需求的准确方法: 1.为所有列创建2个模板。

    1. 并将CellTemplate 更改为CellEditingTemplate 以获取可编辑列。

    2. 在取消/提交后再次将CellTemplate 更改为旧的CellTemplate

      <DataGrid x:Name="DGrid" SelectionUnit="FullRow" AutoGenerateColumns="False" ItemsSource="{Binding Students}" Height="400" CanUserAddRows="False" Margin="10,10,405,18">
      
      <DataGrid.Columns>
          <DataGridTemplateColumn>
              <DataGridTemplateColumn.CellTemplate>
                  <DataTemplate>
                      <StackPanel Width="100">
                          <Button Content="Edit" Click="Button_Click_1"/>
                      </StackPanel>
                  </DataTemplate>
              </DataGridTemplateColumn.CellTemplate>
              <DataGridTemplateColumn.CellEditingTemplate>
                  <DataTemplate>
                      <StackPanel Orientation="Horizontal" Width="100">
                          <Button Content="Cancel" Click="Button_Click_2"/>
                          <Button Content="Commit" Click="Button_Click_3"/>
                      </StackPanel>
                  </DataTemplate>
              </DataGridTemplateColumn.CellEditingTemplate>
          </DataGridTemplateColumn>
          <DataGridTemplateColumn>
              <DataGridTemplateColumn.CellTemplate>
                  <DataTemplate>
                      <TextBlock Text="{Binding Name}"/>
                  </DataTemplate>
              </DataGridTemplateColumn.CellTemplate>
              <DataGridTemplateColumn.CellEditingTemplate>
                  <DataTemplate>
                      <TextBox Background="Aquamarine" Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=Explicit}"/>
                  </DataTemplate>
              </DataGridTemplateColumn.CellEditingTemplate>
          </DataGridTemplateColumn>
      
      </DataGrid.Columns>
      

    代码隐藏

            // Edit
            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                DataGridRow row = (DataGridRow)DGrid.ItemContainerGenerator.ContainerFromItem(DGrid.CurrentItem);
                _showCellsEditingTemplate(row);
            }
    
            // Cancel
            private void Button_Click_2(object sender, RoutedEventArgs e)
            {
                DataGridRow row = (DataGridRow)DGrid.ItemContainerGenerator.ContainerFromItem(DGrid.CurrentItem);
                _showCellsNormalTemplate(row);
            }
    
            // Commit
            private void Button_Click_3(object sender, RoutedEventArgs e)
            {
                DataGridRow row = (DataGridRow)DGrid.ItemContainerGenerator.ContainerFromItem(DGrid.CurrentItem);
                _showCellsNormalTemplate(row, true);
            }
    
            private void _showCellsEditingTemplate(DataGridRow row)
            {
                foreach (DataGridColumn col in DGrid.Columns)
                {
                    DependencyObject parent = VisualTreeHelper.GetParent(col.GetCellContent(row));
                    while (parent.GetType().Name != "DataGridCell")
                        parent = VisualTreeHelper.GetParent(parent);
    
                    DataGridCell cell = ((DataGridCell)parent);
                    DataGridTemplateColumn c = (DataGridTemplateColumn)col;
                    if(c.CellEditingTemplate !=null)
                        cell.Content = ((DataGridTemplateColumn)col).CellEditingTemplate.LoadContent();
                }
            }
    
            private void _showCellsNormalTemplate(DataGridRow row, bool canCommit = false)
            {
                foreach (DataGridColumn col in DGrid.Columns)
                {
                    DependencyObject parent = VisualTreeHelper.GetParent(col.GetCellContent(row));
                    while (parent.GetType().Name != "DataGridCell")
                        parent = VisualTreeHelper.GetParent(parent);
    
                    DataGridCell cell = ((DataGridCell)parent);
                    DataGridTemplateColumn c = (DataGridTemplateColumn)col;
                    if (col.DisplayIndex != 0)
                    {
                        if (canCommit == true)
                            ((TextBox)cell.Content).GetBindingExpression(TextBox.TextProperty).UpdateSource();
                        else
                            ((TextBox)cell.Content).GetBindingExpression(TextBox.TextProperty).UpdateTarget();
                    }
                    cell.Content = c.CellTemplate.LoadContent();                
                }
            }     
    
    
    
    public class ViewModel
        {
            ObservableCollection<Student> _students = new ObservableCollection<Student>();
            public ObservableCollection<Student> Students
            { get { return _students; } set { _students = value; } }
    
            public ViewModel()
            {
                Students.Add(new Student() { Name = "Prashant", Address = "123, N2 B, Barkheda" });
                Students.Add(new Student() { Name = "Amit", Address = "123, N2 B, Piplani" });
                Students.Add(new Student() { Name = "Gopi", Address = "Subhash Nagar" });
                Students.Add(new Student() { Name = "S. Sachin", Address = "HabibGanj" });
            }
        }
    
        public class Student
        {
            public string Name { get; set; }
            public string Address { get; set; }
        }
    

    【讨论】:

    • 嗯,这实际上就是我将所有单元格切换到编辑模式的操作。但是如果它失去焦点,它会不断切换回来,有什么解决方法吗?
    • CancelEdit() CommitEdit() 返回 true 但单元格仍保持编辑模式
    • @Tubc 请根据您的需要查看我更新的确切答案。
    • 这太棒了,感谢您解决了我的问题并增加了我在 wpf 方面的知识
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-23
    • 2013-06-27
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    • 2011-04-25
    相关资源
    最近更新 更多