WPF 数据模板事件处理程序
本文关键字:事件处理 程序 数据 WPF | 更新日期: 2023-09-27 18:34:28
我扩展了ListView类,并在单独的资源文件中为它创建了两个DataTemplate
。我的问题是如何在DataTemplate
中为Checkbox
(和其他项目(添加事件处理程序?
我的列表视图.cs
using System.Windows;
using System.Windows.Controls;
namespace WpfCustomControlLibrary1
{
public class MyListView : ListView
{
public enum ListMode
{
List, ListCheck
}
public static readonly DependencyProperty ModeProperty = DependencyProperty.Register
(
"Mode",
typeof(ListMode),
typeof(MyListView),
new PropertyMetadata(ListMode.List)
);
public ListMode Mode
{
get { return (ListMode)GetValue(ModeProperty); }
set { SetValue(ModeProperty, value); }
}
}
}
MyListViewItem.cs
using System.Windows;
using System.Windows.Controls;
namespace WpfCustomControlLibrary1
{
public class MyListViewItem:Control
{
public static readonly DependencyProperty TextProperty = DependencyProperty.Register
(
"Text",
typeof(string),
typeof(MyListViewItem),
new UIPropertyMetadata(string.Empty)
);
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register
(
"IsChecked",
typeof(bool),
typeof(MyListViewItem),
new UIPropertyMetadata(false)
);
public bool IsChecked
{
get { return (bool)GetValue(IsCheckedProperty); }
set { SetValue(IsCheckedProperty, value); }
}
}
}
资源词典.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfCustomControlLibrary1">
<DataTemplate x:Key="ItemTemplate_List">
<TextBlock Text="{Binding Text}" HorizontalAlignment="Left"/>
</DataTemplate>
<DataTemplate x:Key="ItemTemplate_ListCheck">
<Grid>
<CheckBox IsChecked="{Binding IsChecked}"/>
<TextBlock Text="{Binding Text}" Margin="20,0,0,0" HorizontalAlignment="Left"/>
</Grid>
</DataTemplate>
<Style TargetType="{x:Type local:MyListView}">
<Style.Triggers>
<Trigger Property="Mode" Value="List">
<Setter Property="ItemTemplate" Value="{StaticResource ItemTemplate_List}"/>
</Trigger>
<Trigger Property="Mode" Value="ListCheck">
<Setter Property="ItemTemplate" Value="{StaticResource ItemTemplate_ListCheck}"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
您的问题涉及资源文件中Event handlers
及其使用。 对代码隐藏的访问不能直接在资源文件中XAML
存储中表示。
虽然您可以在用户控件的 XAML 中执行以下操作,
<CheckBox Click="CheckBox_OnClick"/>
当样式在单独的资源目录中分离时,这根本不可能。
这就是 ICommand
接口非常有用的地方,通常在 ViewModel 上触发,但也可用于触发代码隐藏。 然后语法变为(如果您希望触发代码隐藏(:-
<CheckBox Command="{Binding CheckBoxClickedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType='MyListView'}}"/>
这将允许您在以下情况下触发MyListView
类中的代码:
- 将名为
CheckBoxClickedCommand
的属性添加到MyListView
类
在该 - 类的属性上添加用于
ICommand
的支持接口
通常使用 RelayCommand
实施,因此您可以提供 Lambda 表达式来简化实施。 在RelayCommand上快速搜索会给你一些指导。
这一切听起来都不错,直到您发现只有某些控件(例如 Button
、Checkbox
、RadioButton
(将Command
模式作为标准实现。
幸运的是,自 Blend 3 以来,我们现在有更多的空间使用行为ICommand
模式,这也是您可能想要研究的东西。
<CheckBox Command="{Binding CheckBoxClickedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<i:InvokeCommandAction Command="{Binding CheckBoxMouseEnterCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Checkbox>
在这里,其他事件(如 MouseEnter
(可用于触发ICommand
调用。 这也意味着不支持 Command=
属性的其他控件也可以调用代码隐藏。