Команды в WPF привязки в шаблон данных DataTemplate
Я использую ItemsControl
для хранения моей коллекции.
The ItemsPanel
это Canvas
на ItemTemplate
блок Border
>StackPanel
>TextBlocks
Я хочу связать команду DataTemplate
чтобы поймать щелчок на блоке (элемент моей коллекции)
код:
<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>
2 ответов
первый объект, который приходит на ум, чтобы быть прикреплены к команда Border
и так как у этого последнего нет Click
событие, я использую MouseLeftButtonDown
, а так как команды используются только с Button
- базовые элементы управления (кнопка, 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 привязан к продуктам, DataContext DataTemplate будет объектом продукта, чтобы избегайте привязки источника команды к предку окна, который ее DataContext привязан к ViewModel, содержащему 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:command:EventToCommand
от MVVM-Light, Если вы не используете MVVM-Light, вы можете просто использовать это вместо этого:
<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>
это должно отлично работать, надеюсь, я объяснил хорошо.
вы можете попробовать что-то вроде этого:
<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>