Reputation: 59
I have a control template:
(1)
<Style x:Key="customItemStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ToggleButton>
<Grid Width="260" Height="58">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="58"/>
<ColumnDefinition Width="202"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="{StaticResource image_resourse}"/>
<Button Grid.Column="1"> Button text </Button>
</Grid>
</ToggleButton>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
It is used to customize ListBoxItems like this: (2)
<ListBox>
...
<ListBoxItem Style="{StaticResource customItemStyle}">
...
</ListBox
I want to set Click
handler of a Button which is inside that template when applying style to ListBoxItem.
(1) - code from styles file
(2) - code from some component definition file
How can I do this?
Upvotes: 4
Views: 3252
Reputation: 1596
You need to make a slight variation to apply the style. Button_Click can be handled
<Window.Resources>
<Style x:Key="{x:Type ListBoxItem}" TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ToggleButton>
<Grid Width="260" Height="58">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="58"/>
<ColumnDefinition Width="202"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="{StaticResource image_resourse}"/>
<Button Grid.Column="1" Click="Button_Click">Button text</Button>
</Grid>
</ToggleButton>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<ListBox >
<ListBoxItem>0ABC</ListBoxItem>
<ListBoxItem>1ABC</ListBoxItem>
<ListBoxItem>2ABC</ListBoxItem>
</ListBox>
</Grid>
Inside xaml.cs, button click can be handled
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("E hoooo");
}
Upvotes: 0
Reputation: 102723
The way to do this is to define an ICommand
on the template. That way, you should have no trouble binding the handler to whatever code you need.
Start by subclassing ListBoxItem
, and include the "ICommand" dependency property:
public class CommandListBoxItem : ListBoxItem
{
public static readonly DependencyProperty ButtonCommandProperty =
DependencyProperty.Register("ButtonCommand", typeof(ICommand), typeof(CommandListBoxItem), null);
public bool ButtonCommand
{
get { return (ICommand)GetValue(ButtonCommandProperty); }
set { SetValue(ButtonCommandProperty, value); }
}
public CommandListBoxItem()
{
DefaultStyleKey = typeof(CommandListBoxItem);
}
}
Now modify the control template to link the command to the button click:
<Style x:Key="customItemStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type custom:CommandListBoxItem}">
<ToggleButton>
<Grid Width="260" Height="58">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="58"/>
<ColumnDefinition Width="202"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="{StaticResource image_resourse}"/>
<Button Grid.Column="1" Command="{TemplateBinding ButtonCommand}"> Button text </Button>
</Grid>
</ToggleButton>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And finally, bind the command property to a command in your view-model (or code-behind):
<ListBox>
...
<custom:CommandListBoxItem Style="{StaticResource customItemStyle}"
ButtonCommand="{Binding CommandFromViewModel}" />
...
</ListBox>
Upvotes: 3