2017-05-05 37 views
0

我正在寻找指定DataTemplate绑定的正确方法。如何在DataTemplate中为Command和CommandParameter设置绑定顺序

对于命令的正确初始化,它与CommandParamter和Commands绑定发生的顺序相关。

这里是一个xaml和一些源代码来说明这一点。 该示例包含4个命令,2个预计无法正确初始化。 2应该正确初始化。 这两个微不足道的情况表现得如预期一样。 这两个DataTemplate案例不像我预期的那样。

XAML:

<Window x:Class="WPFCommand.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:WPFCommand" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
     <Button 
      Command="{Binding CMD1}" 
      CommandParameter="{Binding Parameter1}" 
      >CMD->PAR</Button> 
     <Button 
      CommandParameter="{Binding Parameter2}" 
      Command="{Binding CMD2}" 
      >PAR->CMD</Button> 
     <DataGrid 
      ItemsSource="{Binding DataGridItemsSource}" 
      AutoGenerateColumns="False" 
      HeadersVisibility="None" 
      > 
      <DataGrid.Columns > 
       <DataGridTemplateColumn Width="1*"> 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <Button 
           Command="{Binding CMD4}" 
           CommandParameter="{Binding Parameter4}" 
           >Grid CMD->PAR</Button> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 
       </DataGridTemplateColumn> 
       <DataGridTemplateColumn Width="1*"> 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <Button 
           CommandParameter="{Binding Parameter3}" 
           Command="{Binding CMD3}" 
           >Grid PAR->CMD</Button> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 
       </DataGridTemplateColumn> 
      </DataGrid.Columns> 
     </DataGrid> 
    </StackPanel> 
</Window> 

代码隐藏

namespace WPFCommand 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Diagnostics; 
    using System.Windows; 
    using System.Windows.Input; 

    public class DemoCommand : ICommand 
    { 
     bool? oldCanEx; 
     private string myname; 

     public DemoCommand(string myname) 
     { 
      this.myname = myname; 
     } 

     public event EventHandler CanExecuteChanged = delegate { }; 

     public bool CanExecute(object parameter) 
     { 
      bool newCanEx; 
      if (parameter == null) 
      { 
       Debug.WriteLine($"{myname} CanExecute called with null"); 
       newCanEx = false; 
      } 
      else 
      { 
       Debug.WriteLine($"{myname} CanExecute called with {parameter}"); 
       newCanEx = true; 
      } 

      if (oldCanEx != newCanEx) 
      { 
       Debug.WriteLine($"{myname} CanExecute changed"); 
       oldCanEx = newCanEx; 
       CanExecuteChanged(this, EventArgs.Empty); 
      } 
      return newCanEx; 
     } 

     public void Execute(object parameter) 
     { 
      Debug.WriteLine($"{myname} Execute {parameter}"); 
     } 
    } 

    public class Item 
    { 
     internal Item() { } 
     public DemoCommand CMD3 { get; private set; } = new DemoCommand("CMD3"); 
     public DemoCommand CMD4 { get; private set; } = new DemoCommand("CMD4"); 
     public int Parameter3 { get; private set; } = 7; 
     public int Parameter4 { get; private set; } = 13; 
    } 

    public class MainWindowViewModel 
    { 
     public IEnumerable<Item> DataGridItemsSource { get; private set; } = new List<Item> { new Item() }; 
     public DemoCommand CMD1 { get; private set; } = new DemoCommand("CMD1"); 
     public DemoCommand CMD2 { get; private set; } = new DemoCommand("CMD2"); 
     public int Parameter1 { get; private set; } = 42; 
     public int Parameter2 { get; private set; } = 5; 
    } 

    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      this.DataContext = new MainWindowViewModel(); 
      InitializeComponent(); 
     } 
    } 
} 

CMD1和CMD2是DataTemplate中的外部。 CMD3和CMD4是Inside。 两者在绑定的排序中显示出相同的差异。

这里是调试输出:

CMD1 CanExecute called with null 
CMD1 CanExecute changed 
CMD1 CanExecute called with null 
CMD2 CanExecute called with 5 
CMD2 CanExecute changed 
CMD2 CanExecute called with 5 
CMD4 CanExecute called with null 
CMD4 CanExecute changed 
CMD4 CanExecute called with null 
CMD3 CanExecute called with null 
CMD3 CanExecute changed 
CMD3 CanExecute called with null 

CMD1不能进行正常corretly初始化。 CMD2按预期成功。 CMD4失败。 CMD3失败,我没有想到。

为什么CMD3的参数在命令之前没有绑定?

为DataTemplated Command/CommandParameter绑定编写xaml的正确方法是什么?(最好不要触及代码)?

回答

0

可以通过将DataTemplate内容放入其自己的视图来解决此问题。

使用

<DataTemplate> 
    <local:CommandView /> 
</DataTemplate> 

用的CommandView beeing一个自定义的用户控件。

<UserControl x:Class="WPFCommand.CommandView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:WPFCommand" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <Button 
     CommandParameter="{Binding Parameter3}" 
     Command="{Binding CMD3}" 
     >Grid PAR->CMD</Button> 
</UserControl> 
相关问题