在DataGrid中创建自定义编辑行wpf

Tub*_*ubc 2 c# wpf datagrid

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

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

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

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

我怎么能阻止这个?以及如何使OK按钮提交所有数据?

Anj*_*han 5

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

有一些事件要处理有关编辑:BeginningEdit,CellEditEnding,PreparingCellForEdit.

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

你可以得到DataGridRow,你可以从中循环DataGridCell.有很多教程可以做到这一点.

针对您的特定需求的精确方法:1.为所有列创建2个模板.

  1. 并更改可编辑列的CellTemplatewith CellEditingTemplate.

  2. 取消/提交后再次更改CellTemplateCellTemplate.

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

代码隐藏

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