wpf - WPF 绑定 ListView 双击事件
问题描述
我是 WPF 的新手,所以请原谅以下任何没有意义的内容......
我已经设置了一个视图模型,它绑定到一个 WPF 列表视图数据模板。源对象(属于一个名为 BrowserItem 的类)位于 ObservableCollection 中,我使用 CollectionViewSource 将它们显示在 ListView 中 - 经过几次头痛之后,这确实很好。
我认为最简单的部分是用户双击某物时的处理,但我错了。
附加到 ListView 的事件返回 TextBlock 控件而不是单击的 BrowserItem 源对象。
任何人都可以指出一种在单击控件时获取原始项目(BrowserItem)的简单方法 - 我已经看到了几种方法,但在我简单的头脑中它们似乎都非常复杂。
一个简单的例子会很棒。
这是列表视图的 XAML(如果使用):
<ListView Name="ViewList"
ItemsSource="{Binding GroupItems}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Expander>
<Expander.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Children.Count}"
Value="0">
<Setter Property="Expander.Visibility"
Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</Expander.Style>
<ListBox ItemsSource="{Binding Children}" />
</Expander>
<TextBlock Text="{Binding Name}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding Active}"
Value="true">
<Setter Property="Background"
Value="YellowGreen" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander>
<Expander.Header>
<TextBlock Text="{Binding Name}" />
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
谢谢。
解决方案
您可以使用 EventSetter 将 MouseDoubleClick 事件添加到列表视图,如下所示:
<ListView ItemsSource="{Binding Source}" SelectedItem="{Binding SelectedModel, Mode=TwoWay}">
<!--<Behaviors:Interaction.Triggers>
<Behaviors:EventTrigger EventName="MouseDoubleClick">
<Behaviors:InvokeCommandAction Command="{Binding DataContext.Command, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}" />
</Behaviors:EventTrigger>
</Behaviors:Interaction.Triggers>-->
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<EventSetter Event="MouseDoubleClick" Handler="ListViewItem_MouseDoubleClick" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate DataType="{x:Type local:Model}">
<TextBlock Text="{Binding Age}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
这样,您只需在代码中处理它,而不是在 ViewModel 中。
如果你想在视图模型中处理它,你需要一个这样的类:
public class EventToCommand
{
public static string GetEventName(DependencyObject obj)
{
return (string)obj.GetValue(EventNameProperty);
}
public static void SetEventName(DependencyObject obj, string value)
{
obj.SetValue(EventNameProperty, value);
}
public static readonly DependencyProperty EventNameProperty =
DependencyProperty.RegisterAttached("EventName", typeof(string), typeof(EventToCommand), new PropertyMetadata("", OnEventNameChanged));
public static void OnEventNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}
public static ICommand GetCommand(DependencyObject obj)
{
return (ICommand)obj.GetValue(CommandProperty);
}
public static void SetCommand(DependencyObject obj, ICommand value)
{
obj.SetValue(CommandProperty, value);
}
public static readonly DependencyProperty CommandProperty =
DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(EventToCommand), new PropertyMetadata(OnCommandChanged));
public static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var element = d as FrameworkElement;
EventInfo eventInfo = d.GetType().GetEvent(GetEventName(d));
var eventHandlerMethodInfo = typeof(EventToCommand).GetMethod("Invoke", BindingFlags.Static | BindingFlags.Public);
eventInfo.AddEventHandler(d, Delegate.CreateDelegate(eventInfo.EventHandlerType, eventHandlerMethodInfo));
}
public static void Invoke(object sender,EventArgs e)
{
var command = GetCommand(sender as FrameworkElement);
command.Execute(e);
}
}
并像这样使用 EventToCommand 类:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="local:EventToCommand.EventName" Value="MouseDoubleClick" />
<Setter Property="local:EventToCommand.Command" Value="{Binding DataContext.Command, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}" />
</Style>
</ListView.ItemContainerStyle>
推荐阅读
- angular - 自定义 HostBinding 装饰器在生产模式下不起作用
- php - 以 Symfony 形式上传文件
- excel - 加权平均值、标准差和中位数 - 大小加权(负数)
- ios - 如何使场景完全伸展到宽度。附上我的 Xcode 模拟器的屏幕截图,它没有填满屏幕
- jquery - 如何在带有 CDN 的 Vue 中使用 jquery?
- r - 无法在 2 个不同的 r 表中过滤具有 2 个内部连接的事物
- python - 带有重复标题值的 Pandas read_excel
- css - react-moveable 和 css 模块 - 不能应用 css 样式
- linear-programming - 具有将参数作为 RHS 的约束的线性规划问题
- web-services - Fiddler 看不到 AWS 上的 Web 服务流量