我尝试使用System.Windows.Interactivity将屏幕上元素的鼠标事件绑定到某些命令逻辑。
我有一个简单的Canvas
,带有三个圆圈。实现了减小圆弧半径的命令。将其绑定到Button
的command属性时,效果很好。
不幸的是,当我尝试将此命令绑定到PreviewMouseDown
的{{1}}事件时,它不再起作用。我想念什么?
这是MainWindow.xaml:
Canvas
MainWindow.xaml.cs为空,但根据MVVM原理进行初始化除外:
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:test="clr-namespace:Test"
Title="MainWindow" Height="550" Width="525">
<Window.Resources>
<test:ViewModel x:Key="viewobj"/>
</Window.Resources>
<Grid>
<ItemsControl ItemsSource="{Binding CircleItems, Source={StaticResource viewobj}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="Black" ClipToBounds="True" HorizontalAlignment="Left" Height="400" Margin="50,20,0,0" VerticalAlignment="Top" Width="400">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseDown" >
<i:InvokeCommandAction Command="{Binding StartCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Ellipse Width="{Binding Radius}" Height="{Binding Radius}" Fill="Red"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Content="Button" Command="{Binding StartCommand, Source={StaticResource viewobj}}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="189,474,0,0"/>
</Grid>
</Window>
这是ViewModel.cs:
using System.Windows;
namespace Test
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
CircleItem.cs类:
using System.Collections.ObjectModel;
using System.ComponentModel;
using Test.Model;
namespace Test
{
public class ViewModel : INotifyPropertyChanged
{
public ObservableCollection<CircleItem> CircleItems { get; set; }
private ButtonCommand _StartCommand;
public ButtonCommand StartCommand
{
get { return _StartCommand; }
}
public ViewModel()
{
_StartCommand = new ButtonCommand(UpdateMap, () => {return true;});
CircleItems = new ObservableCollection<CircleItem>();
CircleItems.Add(new CircleItem(20, 20, 40));
CircleItems.Add(new CircleItem(60, 60, 50));
CircleItems.Add(new CircleItem(120, 100, 30));
}
public void UpdateMap()
{
CircleItem.UpdateMap(CircleItems);
}
internal void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null)
{ PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
还有一个简单的RelayCommand.cs类:
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace Test.Model
{
public class CircleItem : INotifyPropertyChanged
{
private double _x;
public double X
{
get { return _x; }
set
{
if (_x != value)
{
_x = value;
RaisePropertyChanged("X");
}
}
}
private double _y;
public double Y
{
get { return _y; }
set
{
if (_y != value)
{
_y = value;
RaisePropertyChanged("Y");
}
}
}
private double _radius;
public double Radius
{
get { return _radius; }
set
{
if (_radius != value)
{
_radius = value;
RaisePropertyChanged("Radius");
}
}
}
public CircleItem(double x, double y, double radius)
{
this.X = x;
this.Y = y;
this.Radius = radius;
}
public static void UpdateMap(ObservableCollection<CircleItem> coll)
{
foreach (var item in coll)
{
item.Radius -= 1;
}
}
internal void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null)
{ PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
请注意,必须安装NuGet程序包“ System.Windows.Interactivity v4.0 for WPF”,此示例才能正常工作。
答案 0 :(得分:1)
您忘记设置Source
中的Binding
:
<Canvas Background="Black" ClipToBounds="True" HorizontalAlignment="Left" Height="400" Margin="50,20,0,0" VerticalAlignment="Top" Width="400">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseDown">
<i:InvokeCommandAction Command="{Binding StartCommand, Source={StaticResource viewobj}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Canvas>