WPF MVVM:在按钮单击时将焦点设置到Datagrid中的当前所选项目

时间:2017-10-24 10:34:14

标签: c# wpf mvvm datagrid focus

我在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>

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

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

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

在第一次尝试中,未在属性中设置路径:

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

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

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

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解决方案完美无缺。

1 个答案:

答案 0 :(得分:2)

以下内容应该有效:

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

您可以将该代码放入Button.Click事件(此处没有任何错误,我们正在做的事情是完全仅查看的事情)或者如果您不喜欢代码隐藏,您可以创建附加的属性\行为