如何使单元格在编辑模式,只要它得到焦点

本文关键字:焦点 单元格 何使 编辑 模式 | 更新日期: 2023-09-27 18:12:49

假设我有一个DataGrid。假设所有列都是TemplateColumns。当任何单元格获得焦点时,我希望它进入EditMode

我已经试过了:

我已经为DataGridCell创建了一个样式如下:

<Style TargetType="{x:Type DataGridCell}">
    <EventSetter Event="GotFocus" Handler="DataGridCell_GotFocus" />
</Style>

在窗口的代码隐藏:

private void DataGridCell_GotFocus(object sender, RoutedEventArgs e)
{
    DataGridCell cell = sender as DataGridCell;
    if (cell != null && !cell.IsEditing && !cell.IsReadOnly)
    {
        cell.IsEditing = true;
    }
}

上面的问题try:

我必须点击单元格使其进入编辑模式

如何使单元格在编辑模式,只要它得到焦点

在焦点上,单元格进入编辑模式,但textBox没有键盘焦点,因此下一个tab键将被textBox吃掉,并将获得焦点。

正如你提到的,你必须按Tab两次将焦点移动到下一个单元格。你可以做的是将焦点放在TextBox上加载事件:

XAML for dummy element:

<DataGridTemplateColumn>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <TextBox Text="{Binding Name}" Loaded="TextBox_Loaded"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

背后的代码:

private void TextBox_Loaded(object sender, RoutedEventArgs e)
{
    (sender as TextBox).Focus();
}

当然,你可以为dataGrid中的所有textbox移动处理程序到一些基本样式,这样你就不必为所有单元格挂钩处理程序。


如果你不想要处理程序,你也可以使用 interactivity 触发器,就像这里定义的那样:

<DataGridTemplateColumn.CellEditingTemplate>
    <DataTemplate>
        <TextBox Text="{Binding Name}">
            <Interactivity:Interaction.Triggers>
                <Interactivity:EventTrigger EventName="Loaded">
                    <local:TakeFocusAction />
                </Interactivity:EventTrigger>
            </Interactivity:Interaction.Triggers>
        </TextBox>
    </DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>

和行为触发动作:

public class TakeFocusAction : TriggerAction<UIElement>
{
    protected override void Invoke(object parameter)
    {
        AssociatedObject.Focus();
    }
}

让它变成可编辑的

BeginEdit()方法使当前单元格进入编辑模式。

示例

    private void DataGridCell_GotFocus(object sender, RoutedEventArgs e)
    {
        DataGridCell cell = sender as DataGridCell;
        if (cell != null && !cell.IsEditing && !cell.IsReadOnly)
        {
            var parent = VisualTreeHelper.GetParent(cell);
            while (parent != null && parent.GetType() != typeof(DataGrid))
            {
                parent = VisualTreeHelper.GetParent(parent);
            }
            DataGrid dGrid = parent as DataGrid;
            dGrid.BeginEdit();
        }
    }

如果您可以访问数据网格,那么查找它可能不需要

    private void DataGridCell_GotFocus(object sender, RoutedEventArgs e)
    {
        DataGridCell cell = sender as DataGridCell;
        if (cell != null && !cell.IsEditing && !cell.IsReadOnly)
        {
            dGrid.BeginEdit();
        }
    }

Update: FocusManager trick

如果焦点是唯一的问题,您可以通过设置FocusManager.FocusedElement来利用FocusManager。试一试,可以的,without any code behind

示例

<DataGridTemplateColumn>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <TextBox Text="{Binding Name}" 
                     FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

注意,我已经设置了FocusedElementTextBox通过绑定到self,这将使文本框的焦点一旦加载(当它进入编辑模式)