WPF数据表格单元格无法退出编辑模式

3

我在使用WPF DataGrid时遇到了一个奇怪的问题。当你点击第一个单元格,输入值然后按Tab键转移到下一个单元格时,第一个单元格没有退出编辑模式。我已经使用下面简化版的模板重现了这个问题:

<DataGrid Name="grid" HorizontalAlignment="Stretch" ItemsSource="{Binding Persons}" Margin="0,10,0,0" VerticalAlignment="Stretch" AutoGenerateColumns="False" CanUserAddRows="True">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="FirstName">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding FirstName}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <TextBox Text="{Binding FirstName}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="LastName">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding LastName}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <TextBox Text="{Binding LastName}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="Age">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Text="{Binding Age}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <TextBox Text="{Binding Age}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

虚拟类的定义如下:

虚拟类的定义如下:

 public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}

代码背后是:

 public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;

        Persons = new ObservableCollection<Person>();
        this.grid.CurrentCellChanged += grid_CurrentCellChanged;
        this.grid.PreparingCellForEdit += grid_PreparingCellForEdit;
    }

    void grid_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
    {
        if (e.EditingElement != null)
            SetFocusToTextBox(e.EditingElement);
    }

    void grid_CurrentCellChanged(object sender, EventArgs e)
    {
        ((DataGrid)sender).BeginEdit();
    }

    public ObservableCollection<Person> Persons { get; set; }

    void SetFocusToTextBox(object obj)
    {
        // Get all children and examine if the child is a TextBox
        object obChild;
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj as DependencyObject); i++)
        {
            obChild = VisualTreeHelper.GetChild(obj as DependencyObject, i);
            if (obChild is TextBox)
            {
                ((TextBox)obChild).Focus();
                break;
            }
            else
                SetFocusToTextBox(obChild);
        }
    }

有人看出问题了吗?你能重现这个问题吗?任何帮助都将不胜感激。

谢谢, Bhanu


我有同样的问题,即无法退出编辑模式。我还没有找到答案。 - user1298925
2个回答

1
数据网格的XAML定义是100%正确的。问题必须在代码后面。我最好的猜测是CurrentCellChanged事件。它可能会被触发两次。第一次是当您离开单元格时,第二次是选择新单元格时。如果是这种情况,您正在将失去焦点的单元格放回编辑模式,因为您没有检查事件的条件。
您应该能够通过简单的调试来验证这一点-在((DataGrid)sender).BeginEdit()处设置断点,并计算它被调用的次数。
我个人使用以下代码进行BeginEdit,它可以无缝工作:
private void dataGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
{
     if (e.AddedCells.Count > 0 && !this.dataGrid.IsReadOnly)
     {
         this.dataGrid.BeginEdit();
     }
}

嘿,感谢你找出了这个问题!你的解决方案是正确的,但我不明白为什么这个问题只会在第一个被点击的单元格中发生。 - bhanu

0
这段代码对我有效:
void grid_CurrentCellChanged(object sender, EventArgs e)
{
     Dispatcher.BeginInvoke(new Action(() =>
     {
           ((DataGrid)sender).BeginEdit();
     }));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接