2016-12-17 5 views
0

J'affiche une collection d'éléments d'interface utilisateur de différents types (Rectangles et Images) dans le canevas. Les deux dérivent du type UIElement.C# - Evénement Click sur plusieurs collections de types UIElement

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

Tout affiche bien, mais je veux avoir un déclencheur d'événements aux événements de souris - lorsque je clique sur/glisser l'élément spécifique sur la toile, je souhaite recevoir cet objet (rectangle ou image). Je voudrais le faire le modèle MVVM. Comment puis-je le faire?

Répondre

0

Vous pouvez mettre en œuvre un comportement attaché qui accroche la PreviewMouseLeftButtonDown de tous UIElements dans votre collection source à une commande du modèle de vue:

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); 
    } 
} 

Vue:

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

Voir Modèle:

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()); 
    }); 
} 

Vous aurez évidemment besoin d'une implémentation de l'interface ICommand. La classe DelegateCommand est disponible dans Prism: https://github.com/PrismLibrary/Prism/blob/master/Source/Prism/Commands/DelegateCommand.cs

Les commandes sont assez essentielles pour une application MVVM, donc vous le saviez probablement déjà. Vous pouvez vous reporter à l'article de blog suivant pour plus d'informations sur la gestion des événements à l'aide des commandes de MVVM: https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/