InvokeCommandAction 没有调用模板绑定

InvokeCommandAction isn't invoking the templatebinding

我正在尝试制作一个可重复使用的控件,它显示由 TemplateBinding 绑定的图像并且是交互式的,最终支持诸如右键单击、中键单击、左键单击之类的东西,通过与视图模型绑定的命令。它还将支持多个叠加层,因此该控件继承自 ItemsControl。

但是 SomeViewModel 的 MouseLeftButtonDownCommand 没有被调用。我在 Generic.xaml 中写了一些测试 ChangePropertyAction,它确实正确地触发了动作,所以这是我在连接命令时做错的事情。

这是代码(抱歉拖了这么久)

在我的Themes\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>

在我的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>

在我的 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");
    }
}
}

请注意,此项目依赖于 MvvmLight nuget 包以及 Expression.Blend.Sdk。

如何正确连接我的 ViewModel 命令,以便通过单击鼠标左键调用它?

您只需将 Generic.xaml 中的 Binding 稍微更改为

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

这现在将正确绑定到您的 CustomControl 中的依赖项 属性 希望对你有帮助