Привязка обработчика событий wpf в стиле

У меня есть стиль, и я хочу привязать команду к EventSetter"s Handler с RelativeSource, Команда находится в viewModel.

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

Проблема в том, что я получаю ошибку, потому что с этим что-то не так (возможно, это невозможно сделать таким простым способом)

Я много гуглил раньше и нашел AttachedCommandBehaviour, но я думаю, что это не работает со стилем.

Не могли бы вы дать несколько советов, как решить эту проблему?

Обновление 13/10/2011

Я нашел это в MVVM Light Toolkit EventToCommand пример программы:

        <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>

Но здесь привязка не в стиле. Как я могу поставить это EventToCommand к стилю кнопки?

3 ответа

Решение

Прямо сейчас вы связываете MouseLeftButtonDown Событие в TextBlock.TextBlockMouseLeftButtonDownCommand, TextBlockMouseLeftButtonDownCommand не является допустимым свойством для TextBlock, и при этом это не похоже на то, что это Обработчик событий.

Я все время использую AttachedCommandBehavior в стилях для подключения Команды к Событию. Синтаксис обычно выглядит так (обратите внимание на DataContextв привязке команд):

<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>

Альтернатива состоит в том, чтобы подключить EventSetter к событию в коде и обработать команду оттуда:

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

Обработчик событий в коде позади...

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)
        }
    }
}

Поскольку вы используете MVVM, я предлагаю вам Galasoft MVVM Light Toolkit EventToCommand

Мой ответ на этот вопрос решает проблему без каких-либо внешних наборов инструментов / библиотек. Тем не менее, он не использует RelativeSourceи это не 100% MVVM. Требуется одна строка кода в обработчике события code-behind.

Другие вопросы по тегам