【问题标题】:WPF MVVM: Set focus to current selected item in Datagrid on button clickWPF MVVM:单击按钮时将焦点设置为Datagrid中的当前选定项目
【发布时间】:2023-03-25 20:20:01
【问题描述】:

我在 Visual Studio 2008 和 NET Framework 3.5 SP1 中有一个 MVVM WPF 应用程序。除其他控件外,此应用还有一个数据网格和一个按钮。

按钮

<Button Grid.Column="1" Command="{Binding CalculateCommand}" FocusManager.FocusedElement="{Binding ElementName=myDataGrid}" HorizontalAlignment="Right">
    <Button.Style>
        <Style TargetType="Button">
            <Setter Property="IsEnabled" Value="True" />                
            <Style.Triggers>
                <DataTrigger Binding="{Binding ElementName=myDataGrid, Path=SelectedItem}" Value="{x:Null}">
                    <Setter Property="IsEnabled" Value="False" />                        
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
    <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
        <Image VerticalAlignment="Center" Source="/MyWPFApp;component/Images/Calculate.png"></Image>
        <TextBlock VerticalAlignment="Center">Calculate</TextBlock>
    </StackPanel>
</Button>

我要做的是在单击按钮后将焦点设置在数据网格中的当前选定项目上,这样当我单击键盘上的向上/向下箭头键时,我可以移动到数据网格中的任何其他项目。

所以我尝试在按钮中设置 FocusManager.FocusedElement 属性,但它不起作用。我也尝试在不指定路径的情况下按原样设置:

FocusManager.FocusedElement="{Binding ElementName=myDataGrid}"

在第一次尝试时,没有在属性中设置 Path:

FocusManager.FocusedElement="{Binding ElementName=myDataGrid}"

当我单击键盘中向上箭头键的向下(单击按钮后)时,它会将焦点更改为 UI 中的另一个控件,该控件不是数据网格中当前选定的项目。

在第二次尝试中,在属性中设置 Path:

FocusManager.FocusedElement="{Binding ElementName=myDataGrid, Path=SelectedItem}"

它什么都不做,既不关注数据网格中当前选定的项目,也不关注任何其他控件。

我也尝试了here 所说的附加行为,但它不起作用:

<Button Grid.Column="1" Command="{Binding CalculateCommand}" classes:EventFocusAttachment.ElementToFocus="{Binding ElementName=myDataGrid}" HorizontalAlignment="Right">

另一次尝试

它适用于第二次点击,第一次点击被忽略。

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        if (myDataGrid.SelectedIndex > -1)
        {
            var selectedRow = (Microsoft.Windows.Controls.DataGridRow)myDataGrid.ItemContainerGenerator.ContainerFromIndex(myDataGrid.SelectedIndex);
            FocusManager.SetIsFocusScope(selectedRow, true);
            FocusManager.SetFocusedElement(selectedRow, selectedRow);
        }
   }

@Evk 解决方案完美运行。

【问题讨论】:

  • 如果我是你 - 我会在 Button.Click 事件中将焦点设置为网格,因为那完全是视图,与视图模型无关。如果您出于某种原因讨厌代码隐藏 - 您可以对附加的属性 \ 行为执行相同的操作。
  • @Evk 看到我在帖子中的最后一行,我刚刚更新。我已经尝试并附加了行为,但它不起作用。
  • 这意味着即使是带有myDataGrid.Focus() 的简单 Button.Click 处理程序也不起作用?
  • @Evk 使用简单的 Button.Click 事件并在代码隐藏中的 Button.Click 事件中设置 myDataGrid.Focus() 不起作用。当我按下向上/向下箭头键时,它不会移动到数据网格中的下一个项目,而是下一个控件获得焦点,具体取决于我是单击向上还是向下箭头键。

标签: c# wpf mvvm datagrid focus


【解决方案1】:

以下应该有效:

if (myDataGrid.SelectedIndex > -1) {
    var container = (DataGridRow) myDataGrid.ItemContainerGenerator.ContainerFromIndex(myDataGrid.SelectedIndex);
    if (container != null) {
        container.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
    }
}

您可以将该代码放入Button.Click 事件中(这里没有错,我们所做的完全是仅查看的事情),或者如果您不喜欢代码隐藏,您可以从中创建附加属性\行为。

【讨论】:

    猜你喜欢
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-06
    • 1970-01-01
    • 1970-01-01
    • 2013-03-17
    • 2018-03-23
    相关资源
    最近更新 更多