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

时间:2016-01-25 08:29:04

标签: c# wpf datagrid

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

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

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

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

我该怎样防止这种情况?以及如何使OK按钮提交所有数据?

1 个答案:

答案 0 :(得分:5)

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

有些事件需要处理:BeginningEditCellEditEndingPreparingCellForEdit

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

您可以获得DataGridRow,您可以从中DataGridCell循环播放CellTemplate。有很多教程可供选择。

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

  1. 并使用CellEditingTemplate更改CellTemplate以获取可修改列。

  2. 在取消/提交后再次使用旧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; }
        }
    

  3. 代码隐藏

    USE [DataPump]
    GO
    
    declare @login VARCHAR(30) = 'UserRevoke'
    
    declare commands cursor for
    SELECT 'Grant View Definition ON ' + schema_name(schema_id) + '.' + [name] + ' TO ' + '[' + REPLACE(REPLACE (@login, '[', ''), ']', '') + ']' 
    FROM sys.all_objects s 
    WHERE type IN ('P', 'V', 'FN', 'TR', 'IF', 'TF', 'U') 
        /*
        P - Stored Procedure 
        V - View 
        FN - SQL scalar-function
        TR - Trigger 
        IF - SQL inlined table-valued function
        TF - SQL table-valued function
        U - Table (user-defined)
        */
        AND is_ms_shipped = 0 
    ORDER BY s.type, s.name 
    
    declare @cmd varchar(max)
    
    open commands
    fetch next from commands into @cmd
    while @@FETCH_STATUS=0
    begin
      exec(@cmd)
      fetch next from commands into @cmd
    end
    
    close commands
    deallocate commands