InvokeCommandAction не вызывает привязку шаблона

Я пытаюсь создать многоразовый элемент управления, который отображает изображение, привязанное к TemplateBinding, и является интерактивным, поддерживая в конечном итоге такие вещи, как щелчок правой кнопкой мыши, щелчок посередине, щелчок левой кнопкой мыши с помощью команд для привязки к модели представления. Он также будет поддерживать несколько наложений, так как этот элемент управления наследуется от ItemsControl.

Однако команда SomeViewModel MouseLeftButtonDownCommand не вызывается. Я написал некоторый тест ChangePropertyAction в Generic.xaml, и он правильно запускает действие, так что это что-то, что я делаю неправильно с подключением команды.

Вот код (извините, что так длинно)

В моих Темах\Generic.xaml

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Custom_ContentControl"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions">


<Style TargetType="{x:Type local:CustomControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomControl}">
                <Grid Background="Red">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="MouseLeftButtonDown">
                            <i:InvokeCommandAction Command="{TemplateBinding MouseLeftButtonDownCommand}" />
                            <!--<ei:ChangePropertyAction TargetName="Image" PropertyName="Visibility" Value="Collapsed" />-->
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                    <Image x:Name="Image" Source="{TemplateBinding ImageSource}" Stretch="Fill" />
                    <ItemsPresenter />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

In my CustomControl.cs

namespace Custom_ContentControl
{
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

public class CustomControl : ItemsControl
{
    static CustomControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl), new FrameworkPropertyMetadata(typeof(CustomControl)));
    }

    public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register(
        "ImageSource", typeof(ImageSource), typeof(CustomControl), new PropertyMetadata(default(ImageSource)));

    public ImageSource ImageSource
    {
        get { return (ImageSource)GetValue(ImageSourceProperty); }
        set { SetValue(ImageSourceProperty, value); }
    }

    public static readonly DependencyProperty MouseLeftButtonDownCommandProperty = DependencyProperty.Register(
        "MouseLeftButtonDownCommand", typeof (ICommand), typeof (CustomControl), new PropertyMetadata(default(ICommand)));

    public ICommand MouseLeftButtonDownCommand
    {
        get { return (ICommand) GetValue(MouseLeftButtonDownCommandProperty); }
        set { SetValue(MouseLeftButtonDownCommandProperty, value); }
    }
}
}

В моем MainWindow.xaml

<Window x:Class="Custom_ContentControl.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
    xmlns:customContentControl="clr-namespace:Custom_ContentControl"
    Title="MainWindow" Height="350" Width="525" 
    d:DataContext="{d:DesignInstance customContentControl:SomeViewModel}">
<Grid>
    <customContentControl:CustomControl ImageSource="Resources/sample.jpg"
                                        MouseLeftButtonDownCommand="{Binding MouseLeftButtonDownCommand}">
        <!--<TextBlock Text="Some sample text" Foreground="White" />-->
    </customContentControl:CustomControl>
</Grid>

In my MainWindow.xaml.cs

namespace Custom_ContentControl
{
using System.Windows;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new SomeViewModel();
    }
}

class SomeViewModel : ViewModelBase
{
    private RelayCommand mouseLeftButtonDownCommand;

    public RelayCommand MouseLeftButtonDownCommand
    {
        get { return mouseLeftButtonDownCommand ?? (mouseLeftButtonDownCommand = new RelayCommand(OnMouseLeftButtonDown)); }
    }

    private void OnMouseLeftButtonDown()
    {
        MessageBox.Show("Button clicked");
    }
}
}

Обратите внимание, что этот проект зависит от пакета nuget MvvmLight вместе с Expression.Blend.Sdk.

Как мне правильно подключить мою команду ViewModel, чтобы она вызывалась щелчком левой кнопки мыши?


person johnildergleidisson    schedule 07.04.2015    source источник


Ответы (1)


Вам просто нужно немного изменить Binding в Generic.xaml на

<i:Interaction.Triggers>
   <i:EventTrigger EventName="MouseLeftButtonDown">
       <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=MouseLeftButtonDownCommand}" />
   </i:EventTrigger>
</i:Interaction.Triggers>

теперь это будет правильно привязываться к свойству зависимости в вашем CustomControl Надеюсь, это поможет

person SWilko    schedule 08.04.2015
comment
Это помогает, большое спасибо. Вы знаете, почему TemplateBinding не работает с EventTrigger? Потому что, если я добавлю кнопку сразу после изображения с <Button Width="100" Height="25" Command="{TemplateBinding MouseLeftButtonDownCommand}" />, команда кнопки будет подключена, как и ожидалось. - person johnildergleidisson; 08.04.2015
comment
Да, это будет работать при запуске команды ViewModel, поскольку DataContext MainWindow является ViewModel, он вызывает команду ViewModel, но НЕ свойство CustomControls MouseLeftButtonDown DependencyProperty. EventTrigger срабатывает в обоих сценариях, но только первый из них подхватывается вашим CustomControl DP. - person SWilko; 08.04.2015