UWP 中通过 XAML 触发设置 ListView 选中项

Trigger to set ListView selected item through XAML in UWP

我有一个包含 TextBox 的 ListView,我想在用户单击其中一个 TextBox 时设置所选项目。

这是我到目前为止尝试过的方法。

<StackPanel Orientation="Vertical">

            <TextBlock Text="Name  Serial"/>
            <ListView ItemsSource="{Binding Items, Mode=OneWay}"
                      SelectedItem="{x:Bind VM.SelectedItem, Mode=TwoWay}">
                <ListView.Resources>
                    <Style TargetType="ListViewItem">
                        <Style.Triggers>
                            <Trigger Property="IsKeyboardFocusWithin" Value="True">
                                <Setter Property="IsSelected" Value="True"/>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </ListView.Resources>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBox Text="{Binding Name, Mode=TwoWay}"/>
                            <TextBox Text="{Binding Serial, Mode=TwoWay}"/>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackPanel>

问题是 UWP 不支持样式触发器。有其他方法可以实现吗?

一般来说,Trigger可以换成Behavior。这是一个例子 -

首先,如果您还没有安装此 nuget 软件包,则需要安装它。

Install-Package Microsoft.Xaml.Behaviors.Uwp.Managed

然后,您想将这些命名空间添加到您的 XAML。

xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:Core="using:Microsoft.Xaml.Interactions.Core"

有了这些命名空间,您现在可以使用之前安装的 nuget 包附带的 EventTriggerBehavior。您基本上需要将其附加到控制选择的所有 TextBoxes。

<TextBox>
    <Interactivity:Interaction.Behaviors>
        <Core:EventTriggerBehavior EventName="GotFocus">
            <local:SelectSelectorItemAction />
        </Core:EventTriggerBehavior>
    </Interactivity:Interaction.Behaviors>
</TextBox>

在这种情况下,EventTriggerBehavior 的作用是,每当调用 TextBox 的事件 GotFocus 时,将执行名为 SelectSelectorItemActionIAction (通过 IAction.Execute)。 SelectSelectorItemAction 是您唯一需要构建的东西。

public class SelectSelectorItemAction : DependencyObject, IAction
{
    public object Execute(object sender, object parameter)
    {
        var textBox = (FrameworkElement)sender;
        var selectorItem = textBox.GetParent<SelectorItem>();

        selectorItem.IsSelected = true;
        return true;
    }
}

public static class Extensions
{
    public static T GetParent<T>(this DependencyObject element) where T : DependencyObject
    {
        var parent = VisualTreeHelper.GetParent(element);

        // C# 7 pattern matching feature. If you are not using C# 7, change it.
        if (parent is T p)
        {
            return p;
        }

        return GetParent<T>(parent);
    }
}

代码非常简单。它所做的只是搜索 Visual Tree 并找到 SelectorItem,它是 ListViewItem 的基础 class。这样您也可以为 GridView 重用相同的 SelectSelectorItemAction