I have extended ListView class and created two DataTemplate
for it in the separate Resource file. My question is how I can add event handlers for the Checkbox
(and other items) in the DataTemplate
?
MyListView.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); }
}
}
}
ResourceDictionary.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>
Your question refers to Event handlers
and the use of them in Resource files. Access to the code-behind cannot be expressed directly in XAML
stored in resource files.
While you are able to do the following in the XAML of a UserControl,
<CheckBox Click="CheckBox_OnClick"/>
this is simply not possible when the style is detached in a separate resource directory.
This is where the ICommand
interface becomes useful to trigger, usually, on the ViewModel but can also be used to trigger code-behind. The syntax then becomes (if you are looking to trigger code-behind):-
<CheckBox Command="{Binding CheckBoxClickedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType='MyListView'}}"/>
This would allow you to trigger code in your MyListView
class if you:-
CheckBoxClickedCommand
to your MyListView
class ICommand
on that property of that class It is common to use the RelayCommand
implementation so you can supply Lambda Expressions to simplify the implementation. A quick search on RelayCommand will give you some guidance.
This all sounds good until you find out that only certain controls (eg Button
, Checkbox
, RadioButton
) implement the Command
pattern as standard.
Luckily since Blend 3 we now have more scope to use the ICommand
pattern using Behaviours, again something you might want to research.
<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>
Here other events such as MouseEnter
can be used to fire off an ICommand
call. This also means other controls that did not support the Command=
property can also call the code-behind.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.