2016-12-17 18 views
0

我在画布中显示了不同类型(矩形和图像)的UI元素的集合。两者都来自UIElement类型。C# - 多个UIElement类型集合上的Click事件

<ItemsControl ItemsSource="{Binding UiElementsCollection}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Canvas HorizontalAlignment="Left" VerticalAlignment="Top"> 
      </Canvas> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
</ItemsControl> 

一切显示正常,但我想有一个事件触发鼠标事件 - 当我点击/拖过画布的特​​定元素,我想获得这个对象(矩形或图像)。我想这样做的MVVM模式。我该怎么做?

回答

0

您可以实现一个附加的行为挂钩起来的PreviewMouseLeftButtonDown源集合中的所有UI元素的向视图模型的命令:

public class MyBehavior 
{ 
    public static readonly DependencyProperty MouseLeftButtonDownCommandProperty 
     = DependencyProperty.RegisterAttached("MouseLeftButtonDownCommand", 
      typeof(ICommand), typeof(MyBehavior), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnMouseLeftButtonDownCommandPropertyChanged))); 

    public static void SetMouseLeftButtonDownCommand(UIElement element, ICommand value) 
    { 
     element.SetValue(MouseLeftButtonDownCommandProperty, value); 
    } 
    public static ICommand GetMouseLeftButtonDownCommand(UIElement element) 
    { 
     return (ICommand)element.GetValue(MouseLeftButtonDownCommandProperty); 
    } 

    private static void OnMouseLeftButtonDownCommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     UIElement element = d as UIElement; 
     element.PreviewMouseLeftButtonDown += Element_MouseLeftButtonDown; 
    } 

    private static void Element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     UIElement element = sender as UIElement; 
     ICommand command = GetMouseLeftButtonDownCommand(element); 
     if (command != null) 
      command.Execute(element); 
    } 
} 

查看:

<Window x:Class="WpfApplication1.Window6" 
     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" 
     xmlns:local="clr-namespace:WpfApplication1" 
     mc:Ignorable="d" 
     Title="Window6" Height="300" Width="300"> 
    <Window.DataContext> 
     <local:ViewModel /> 
    </Window.DataContext> 
    <Grid> 
     <ItemsControl ItemsSource="{Binding UiElementsCollection}"> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <Canvas HorizontalAlignment="Left" VerticalAlignment="Top"> 
        </Canvas> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
      <ItemsControl.ItemContainerStyle> 
       <Style> 
        <Setter Property="local:MyBehavior.MouseLeftButtonDownCommand" 
          Value="{Binding DataContext.TheCommand, RelativeSource={RelativeSource AncestorType=Window}}" /> 
       </Style> 
      </ItemsControl.ItemContainerStyle> 
     </ItemsControl> 
    </Grid> 
</Window> 

查看型号:

public class ViewModel 
{ 
    public ObservableCollection<UIElement> UiElementsCollection { get; } = new ObservableCollection<UIElement>() 
     { 
      new Button { Content = "btn" }, 
      new Border { Background = Brushes.Yellow, Width = 10, Height = 10 } 
     }; 

    public ICommand TheCommand { get; } = new DelegateCommand<UIElement>(element => 
    { 
     MessageBox.Show(element.GetType().ToString()); 
    }); 
} 

您显然需要实现ICommand接口。 DelegateCommand类可在Prism中使用:https://github.com/PrismLibrary/Prism/blob/master/Source/Prism/Commands/DelegateCommand.cs

命令对于MVVM应用程序来说非常重要,尽管您可能已经知道这一点。有关如何使用MVVM中的命令处理事件的更多信息,请参阅以下博文:https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/