2014-07-22 8 views
5

내 컬렉션을 보유하려면 ItemsControl을 사용하고 있습니다. ItemsPanelItemTemplate 내가 블록 (내 컬렉션의 항목)에 클릭을 잡으려고 DataTemplate의 명령을 바인딩 할 Border>StackPanel>TextBlocks 의 블록하는 Canvas입니다DataTemplate에서 WPF 명령 바인딩

코드 :

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

답변

10

명령에 첨부되는 것을 염두에 두는 첫 번째 개체는 Border이고이 후자에는 Click 이벤트가 없으므로 MouseLeftButtonDown을 사용하고 명령은 재치 만 사용하므로 시간 Button -base 컨트롤 (버튼,의 RadioButton은, 체크 박스, RepeatButton는 ...) 당신이 EventTriggers을 필요로 할 것이다, 당신의 DataTemplate은 다음과 같아야합니다

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

당신의 ItemsControl에의 소스가 제품에 결합되어 있기 때문에 다음 DataTemplate을의의 DataContext를

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 : :이 command:EventToCommand이 경우, MVVM 빛에서 당신이 RelayCommand를 포함 그의 DataContext가 ViewModel에 바인딩되는 창 조상에 명령의 소스를 결합하는 것을 방지하기 위해, 제품의 객체가 될 것이다 MVVM-Light를 사용하고 있지 않습니다.

이것은 제대로 작동해야합니다. 잘 설명했으면 좋겠어요. 당신은 이런 식으로 뭔가하려고 할 수 있습니다

7

: 바인딩

<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 = "{SomeCommand 바인딩} ''이 DataTemplate을의 DataContext에이 제품으로 설정됩니다 (모델) ViewModel이 아닌 – AymenDaoudi

+1

충분히 정교합니다. 편집 됨. – Den

관련 문제