【问题标题】:How to bring cell in edit mode as soon as it gets focus如何在单元格获得焦点后立即将其置于编辑模式
【发布时间】:2014-07-12 12:28:43
【问题描述】:

假设我有一个 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;
    }
}

上面尝试的问题:

我必须单击单元格才能使其进入编辑模式。

【问题讨论】:

  • 那么,您的要求是什么?单击单元格获得焦点并进入编辑模式,这对我来说似乎很完美。不是吗?
  • 不,当我在一个单元格上按 TAB 键时,另一个单元格会获得焦点,但不会进入编辑模式。我的意思是我想在单元格获得焦点后立即将单元格置于编辑模式。
  • 根据当前的行为,我必须按两次 TAB 才能使单元格处于编辑模式。
  • 您是否为您的 TemplateColumn 定义了 CellEditingTemplate 并在其中放置了 TextBox?
  • @RohitVats 是的,我完全按照你的要求做了

标签: c# wpf datagrid


【解决方案1】:

在获得焦点时,单元格进入编辑模式,但文本框没有键盘焦点,因此下一个标签按下将被文本框吃掉并获得焦点。

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

XAML 用于虚拟元素:

<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 中所有文本框的某种基本样式,这样您就不必为所有单元格挂钩处理程序。


如果您不想拥有处理程序,您也可以使用 interactivity 触发器(如定义的here)来做到这一点:

<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();
    }
}

【讨论】:

    【解决方案2】:

    这是一个让它可编辑的技巧

    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();
            }
        }
    

    更新:FocusManager技巧

    如果焦点是您可以通过设置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>
    

    请注意,我已通过绑定到 self 将 FocusedElement 设置为 TextBox,这将使 TextBox 在加载后成为焦点(当它进入编辑模式时)

    【讨论】:

    • 我可以访问数据网格,但结果是一样的
    • 是否正在调用事件处理程序? dGrid.BeginEdit() 被执行了吗?
    猜你喜欢
    • 1970-01-01
    • 2014-06-17
    • 2019-12-03
    • 1970-01-01
    • 2012-08-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 2011-05-27
    相关资源
    最近更新 更多