【问题标题】:WPF Binding not working on nested listviewWPF绑定不适用于嵌套列表视图
【发布时间】:2016-04-01 19:18:35
【问题描述】:

我有一个带有下拉按钮的树视图。下拉按钮显示用于将节点添加到树的选项。当用户选择一个选项时,我希望一个命令被触发并由父用户控件中的命令处理。仅供参考,使用 catel MVVM 框架。

XAML

<Grid Margin="10">
  <TreeView x:Name="CriteriaTreeView" ItemsSource="{Binding Criteria}">
    <i:Interaction.Triggers>
      <i:EventTrigger EventName="SelectedItemChanged">
        <catel:EventToCommand Command="{Binding NodeSelectionChanged}" CommandParameter="{Binding ElementName=CriteriaTreeView, Path=SelectedItem}" DisableAssociatedObjectOnCannotExecute="False" />
      </i:EventTrigger>
    </i:Interaction.Triggers>
    <TreeView.Resources>
      <HierarchicalDataTemplate DataType="{x:Type self:Group}" ItemsSource="{Binding Items}">
        <StackPanel Orientation="Horizontal">
          <ComboBox ItemsSource="{Binding OperatorOptions}" SelectedValue="{Binding SelectedOperator}" DisplayMemberPath="DisplayText" SelectedValuePath="Value" />
        </StackPanel>
      </HierarchicalDataTemplate>
      <DataTemplate DataType="{x:Type self:Leaf}">
        <StackPanel Orientation="Horizontal">
          <TextBlock Text="Where Account Number " />
          <ComboBox ItemsSource="{Binding OperatorOptions}" SelectedValue="{Binding SelectedOperator}" DisplayMemberPath="DisplayText" SelectedValuePath="Value" />
          <TextBox Text="{Binding Value}" Width="50" />
        </StackPanel>
      </DataTemplate>
      <DataTemplate DataType="{x:Type self:NodeFactory}">
        <xctk:DropDownButton Content="Add Condition" IsOpen="{Binding IsOpen}">
          <xctk:DropDownButton.DropDownContent>
            <ListView ItemsSource="{Binding AddOptions}" SelectedValue="{Binding SelectedOption}">
              <i:Interaction.Triggers>
                <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
                  <catel:EventToCommand Command="{Binding Source={x:Reference ManageSyncControl}, Path=DataContext.AddNode}" DisableAssociatedObjectOnCannotExecute="False" />
                </i:EventTrigger>
              </i:Interaction.Triggers>
              <ListView.ItemTemplate>
                <DataTemplate>
                  <WrapPanel>
                    <TextBlock Text="{Binding DisplayText}" />
                  </WrapPanel>
                </DataTemplate>
              </ListView.ItemTemplate>
            </ListView>
          </xctk:DropDownButton.DropDownContent>
        </xctk:DropDownButton>
      </DataTemplate>
    </TreeView.Resources>
  </TreeView>
</Grid>

视图模型

    public class ManageSyncedAccountsViewModel: ViewModelEventBase {
      public ManageSyncedAccountsViewModel(IEventAggregator eventAggregator): base(eventAggregator) {
        AddNode = new Command(OnAddNode);
        NodeSelectionChanged = new Command < Node > (OnNodeSelectionChanged);

        var root = new Group("Root");
        var g1 = new Group("Group 1");
        g1.AddNode(new Leaf("Leaf 1"));
        g1.AddNode(new Leaf("Leaf 2"));
        var g2 = new Group("Group2");
        g2.AddNode(new Leaf("Leaf 3"));
        g2.AddNode(new Leaf("Leaf 4"));
        root.AddNode(g1);
        root.AddNode(g2);
        root.AddNode(new Leaf("Leaf 5"));

        Criteria = new List < Group > {
          root
        };
      }

      private void OnNodeSelectionChanged(Node target) {
        SelectedNode = target;
      }

      private void OnAddNode() {
        Console.Out.WriteLine("WOOHOO");
      }

      public List < Group > Criteria {
        get {
          return GetValue < List < Group >> (CriteriaProperty);
        }
        set {
          SetValue(CriteriaProperty, value);
        }
      }

      public static readonly PropertyData CriteriaProperty = RegisterProperty(nameof(Criteria), typeof(List < Group > ));


      public Node SelectedNode {
        get {
          return GetValue < Node > (SelectedNodeProperty);
        }
        set {
          SetValue(SelectedNodeProperty, value);
        }
      }

      public static readonly PropertyData SelectedNodeProperty = RegisterProperty(nameof(SelectedNode), typeof(Node));

      public Command AddNode {
        get;
        private set;
      }
      public Command < Node > NodeSelectionChanged {
        get;
        private set;
      }
    }

当我运行这个时,我得到一个绑定错误:

System.Windows.Data 错误:40:BindingExpression 路径错误: 在“对象”“MainWindowViewModel”上找不到“AddNode”属性 (哈希码=-1718218621)'。 BindingExpression:Path=DataContext.AddNode; DataItem='ManageSyncedAccountsView'(名称='ManageSyncControl');目标 元素是“EventToCommand”(HashCode=6678752);目标属性是 “命令”(输入“ICommand”)

我尝试使用相对源搜索来搜索祖先类型和元素名称,但这两个选项都返回了更加令人困惑的错误消息。显然我在这里遗漏了一些东西。

谢谢。

【问题讨论】:

    标签: wpf data-binding catel


    【解决方案1】:

    根据您问题中的错误消息,Button 的 DataContext 的类型为MainWindowViewModel,但拥有AddNode 命令的类称为ManageSyncedAccountsViewModel。

    System.Windows.Data 错误:40:BindingExpression 路径错误:在“对象”“MainWindowViewModel”(HashCode=-1718218621)上找不到“AddNode”属性。 BindingExpression:Path=DataContext.AddNode; DataItem='ManageSyncedAccountsView'(名称='ManageSyncControl');目标元素是“EventToCommand”(HashCode=6678752);目标属性是“Command”(输入“ICommand”)

    尝试将AddNode 放在按钮可以看到的MainWindowViewModel 上。

    【讨论】:

    • 而“盯着问题看太久不仔细看”的问题又来了。非常感谢 Ed,大脑被卡住了,忽略了粗体部分!
    猜你喜欢
    • 1970-01-01
    • 2020-11-18
    • 2018-06-16
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 2013-12-06
    • 1970-01-01
    相关资源
    最近更新 更多