Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wpf eventsetter handler binding in style

Tags:

c#

binding

wpf

I have a style, and I want to bind a command to the EventSetter's Handler with RelativeSource. The command is in the viewModel.

<Style x:Key="ItemTextBlockEventSetterStyle" TargetType="{x:Type TextBlock}">
    <EventSetter Event="MouseLeftButtonDown" 
                 Handler="{Binding TextBlockMouseLeftButtonDownCommand, 
                           RelativeSource={RelativeSource Self}}"/>
</Style>

The problem is that I get an error, because something is wrong with this (maybe it's not possible to do this in such easy way)

I've googled a lot before, and I found the AttachedCommandBehaviour, but I think it doesn't work with style.

Could you give some hints on how to solve this problem?

Update 13/10/2011

I found this in the MVVM Light Toolkit EventToCommand example program:

        <Button Background="{Binding Brushes.Brush1}"
            Margin="10"
            Style="{StaticResource ButtonStyle}"
            Content="Simple Command"
            Grid.Row="1"
            ToolTipService.ToolTip="Click to activate command">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Click">
                <cmd:EventToCommand Command="{Binding SimpleCommand}" />
            </i:EventTrigger>
            <i:EventTrigger EventName="MouseLeave">
                <cmd:EventToCommand Command="{Binding ResetCommand}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Button>

But here, the binding isn't in the style. How can I put this EventToCommand to the style of the button?

like image 580
Zoltán Barna Avatar asked Oct 13 '11 13:10

Zoltán Barna


2 Answers

Right now you are binding the MouseLeftButtonDown Event to TextBlock.TextBlockMouseLeftButtonDownCommand. TextBlockMouseLeftButtonDownCommand is not a valid property for a TextBlock, nor does it sound like it's an Event Handler.

I use the AttachedCommandBehavior all the time in styles for hooking up a Command to an Event. The syntax usually looks like this (note the DataContextin the Command Binding):

<Style x:Key="ItemTextBlockEventSetterStyle" TargetType="{x:Type TextBlock}">
    <Setter Property="local:CommandBehavior.Event" Value="MouseLeftButtonDown" />
    <Setter Property="local:CommandBehavior.Command"
            Value="{Binding DataContext.TextBlockMouseLeftButtonDownCommand, 
                            RelativeSource={RelativeSource Self}}" />
</Style>

The alternative is to hook the EventSetter up to an event in the code-behind, and process the command from there:

<Style x:Key="ItemTextBlockEventSetterStyle" TargetType="{x:Type TextBlock}">
    <EventSetter Event="MouseLeftButtonDown" 
                 Handler="TextBlockMouseLeftButtonDown"/>
</Style>

Event handler in code behind...

void TextBlockMouseLeftButtonDown(object sender, MouseEventArgs e)
{
    var tb = sender as TextBlock;
    if (tb != null)
    {
        MyViewModel vm = tb.DataContext as MyViewModel;

        if (vm != null && TextBlockMouseLeftButtonDownCommand != null
            && TextBlockMouseLeftButtonDownCommand.CanExecute(null))
        {
            vm.TextBlockMouseLeftButtonDownCommand.Execute(null)
        }
    }
}
like image 195
Rachel Avatar answered Oct 24 '22 00:10

Rachel


As you are using MVVM, I suggest you Galasoft MVVM Light Toolkit EventToCommand

like image 5
Philippe Lavoie Avatar answered Oct 24 '22 00:10

Philippe Lavoie