簡體   English   中英

在WPF MVVM中綁定到鼠標事件

[英]Binding to a mouse event in WPF MVVM

我嘗試使用System.Windows.Interactivity將屏幕上元素的鼠標事件綁定到某些命令邏輯。

我有一個帶有三個圓圈的簡單Canvas 實現了減小圓弧半徑的命令。 當綁定到Button的command屬性時,這種方法可以正常工作。

不幸的是,當我嘗試將此命令綁定到CanvasPreviewMouseDown事件時,它不再起作用。 我想念什么?

這是MainWindow.xaml:

<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>

MainWindow.xaml.cs為空,但根據MVVM原理進行初始化除外:

using System.Windows;

namespace Test
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

這是ViewModel.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;
    }
}

CircleItem.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;
    }
}

還有一個簡單的RelayCommand.cs類:

using System;
using System.Windows.Input;

namespace Test
{
    public class ButtonCommand : ICommand
    {
        private Action WhattoExecute;
        private Func<bool> WhentoExecute;
        public ButtonCommand(Action What, Func<bool> When)
        {
            WhattoExecute = What;
            WhentoExecute = When;
        }
        public bool CanExecute(object parameter)
        {
            return WhentoExecute();
        }
        public void Execute(object parameter)
        {
            WhattoExecute();
        }

        public event EventHandler CanExecuteChanged;
    }
}

請注意,必須安裝NuGet軟件包“用於WPF的System.Windows.Interactivity v4.0”,此示例才能正常工作。

您忘記設置Binding Source

<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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM