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
。您基本上需要将其附加到控制选择的所有 TextBox
es。
<TextBox>
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="GotFocus">
<local:SelectSelectorItemAction />
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</TextBox>
在这种情况下,EventTriggerBehavior
的作用是,每当调用 TextBox
的事件 GotFocus
时,将执行名为 SelectSelectorItemAction
的 IAction
(通过 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
。
我有一个包含 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
。您基本上需要将其附加到控制选择的所有 TextBox
es。
<TextBox>
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="GotFocus">
<local:SelectSelectorItemAction />
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</TextBox>
在这种情况下,EventTriggerBehavior
的作用是,每当调用 TextBox
的事件 GotFocus
时,将执行名为 SelectSelectorItemAction
的 IAction
(通过 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
。