Подтвердить что ты не робот

Привязка wpf eventsetter в стиле

У меня есть стиль, и я хочу привязать команду к EventSetter 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 в стиль кнопки?

4b9b3361

Ответ 1

Прямо сейчас вы привязываете событие 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)
        }
    }
}

Ответ 3

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