WPF中DataTemplate的命令绑定

7

我正在使用ItemsControl来保存我的集合。 ItemsPanel是一个CanvasItemTemplate是由一个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个回答

12

首先想到要附加到该命令的对象是 Border,由于后者没有 Click 事件,因此我将使用 MouseLeftButtonDown,并且由于命令仅与“Button”基础控件(Button、RadioButton、CheckBox、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源已绑定到Products,因此DataTemplate的DataContext将是一个Product对象,为了避免这种情况,您应该将命令的源绑定到窗口祖先,它的DataContext绑定到包含RelayCommand的ViewModel:

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>

这应该完美运作,希望我解释得清楚。


10

你可以尝试类似这样的方法:

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

对于输入绑定,加1分;对于Command="{Binding SomeCommand}",扣1分;DataTemplate的DataContext设置为Product(Model),而不是ViewModel。 - AymenDaoudi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接