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 中的依赖项 属性
希望对你有帮助
我正在尝试制作一个可重复使用的控件,它显示由 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 中的依赖项 属性 希望对你有帮助