2014-07-22 14 views
5

Sto usando ItemsControl per contenere la mia raccolta. Il ItemsPanel è un Canvas, il ItemTemplate è un blocco di Border>StackPanel>TextBlocks voglio associare un comando nel DataTemplate per prendere il click su un blocco (oggetto della mia collezione)Binding comando WPF in DataTemplate

Codice:

<Grid Grid.Row="1" Grid.Column="1" > 
     <ItemsControl ItemsSource="{Binding Products}"> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <helpers:DragCanvas 
         HorizontalAlignment="Stretch" 
         VerticalAlignment="Stretch" 
         AllowDragging="True" 
         AllowDragOutOfView="False" /> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <!-- The border and its content is what I see 
        on my canvas, I want to bind a command here (on click do something) --> 
        <Border BorderThickness="1" BorderBrush="Gold"> 
         <StackPanel Orientation="Horizontal"> 
          <TextBlock Text="{Binding Path=Name}" /> 
          <TextBlock Text="{Binding Path=Price}" /> 
         </StackPanel> 
        </Border> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate>  
     </ItemsControl> 
    </Grid> 

risposta

10

il primo oggetto che viene in mente da allegare al comando è la Border e dal momento che quest'ultima non dispone di un evento Click, Userò MouseLeftButtonDown, e dal momento che i comandi vengono utilizzati solo ingegno h Button controlli -BASE (Button, RadioButton, CheckBox, RepeatButton ...) vi sarà bisogno EventTriggers, il vostro DataTemplate dovrebbe essere simile a questo:

<DataTemplate> 
     <Border BorderThickness="1" BorderBrush="Gold"> 
      <i:Interaction.Triggers> 
        <i:EventTrigger EventName="MouseLeftButtonDown"> 
          <command:EventToCommand Command="{Binding RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}, Path=DataContext.MouseLeftButtonDown }"/> 
        </i:EventTrigger> 
      </i:Interaction.Triggers> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding Path=Name}" /> 
       <TextBlock Text="{Binding Path=Price}" /> 
      </StackPanel> 
     </Border> 
</DataTemplate> 

Dal fonte del ItemsControl è destinata a prodotti poi, DataContext del DataTemplate sarà un oggetto prodotto, per evitare che si dovrebbe legare fonte del comando per l'antenato finestra, che la sua DataContext è legata al ViewModel che contiene il RelayCommand:

public class MainViewModel : ViewModelBase 
{ 


    public class Product 
    { 
     public string Name { get; set; } 
     public string Price { get; set; } 
    } 

    public List<Product> Products 
    { 
     get 
     { 
      return new List<Product>() 
        { 
         new Product(){Name = "Product1",Price = "Price1"}, 
         new Product(){Name = "Product2",Price = "Price2"} 
        }; 
     } 
    } 

    public RelayCommand MouseLeftButtonDown { get; set; } 

    public MainViewModel() 
    { 
      MouseLeftButtonDown = new RelayCommand(()=> MessageBox.Show("Message","Hi")); 
    } 
} 

PS: il command:EventToCommand da MVVM-Light, se non stai usando MVVM-Light puoi farlo basta andare con questo, invece:

<i:Interaction.Triggers> 
     <i:EventTrigger EventName="MouseLeftButtonDown"> 
       <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}, Path=DataContext.MouseLeftButtonDown }" >    
       </i:InvokeCommandAction> 
     </i:EventTrigger> 
</i:Interaction.Triggers> 

Questo dovrebbe funzionare perfettamente, spero ho spiegato bene.

7

Si può provare qualcosa di simile:

<DataTemplate> 
     <Border BorderThickness="1" BorderBrush="Gold"> 
     <Border.InputBindings> 
      <MouseBinding MouseAction="LeftClick" Command="{Binding DataContext.SomeCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}"/> 
     </Border.InputBindings> 

     <StackPanel Orientation="Horizontal"> 
      <TextBlock Text="{Binding Path=Name}" /> 
      <TextBlock Text="{Binding Path=Price}" /> 
      </StackPanel> 
      </Border> 
</DataTemplate> 
+0

+1 per l'ingresso di legame, -1 per il 'Command = "{Binding SomeCommand}"', il DataContext di DataTemplate è impostato al Prodotto (Modello) non al ViewModel – AymenDaoudi

+1

Abbastanza corretto. Modificato. – Den