【问题标题】:WPF Command binding in DataTemplateDataTemplate 中的 WPF 命令绑定
【发布时间】:2014-07-22 02:47:19
【问题描述】:

我正在使用ItemsControl 来保存我的收藏。 ItemsPanelCanvasItemTemplateBorder>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>

【问题讨论】:

    标签: wpf mvvm data-binding datatemplate


    【解决方案1】:

    想到要附加到命令的第一个对象是Border,由于后者没有Click 事件,我将使用MouseLeftButtonDown,因为仅使用命令使用Button-base 控件(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 的 Window 祖先:

    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>
    

    这应该很好用,希望我解释清楚。

    【讨论】:

      【解决方案2】:

      你可以试试这样的:

      <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 表示输入绑定,-1 表示Command="{Binding SomeCommand}",DataTemplate 的 DataContext 设置为 Product (Model) 而不是 ViewModel
      猜你喜欢
      • 2017-01-31
      • 1970-01-01
      • 1970-01-01
      • 2019-10-18
      • 1970-01-01
      • 1970-01-01
      • 2013-05-29
      • 2016-11-22
      • 1970-01-01
      相关资源
      最近更新 更多