WPF 绑定不适用于嵌套列表视图
WPF Binding not working on nested listview
我有一个带有下拉按钮的树视图。下拉按钮显示用于向树中添加节点的选项。当用户选择一个选项时,我希望命令被触发并由父用户控件中的命令处理。仅供参考,使用 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 Error: 40 : BindingExpression path error:
'AddNode' property not found on 'object' ''MainWindowViewModel'
(HashCode=-1718218621)'. BindingExpression:Path=DataContext.AddNode;
DataItem='ManageSyncedAccountsView' (Name='ManageSyncControl'); target
element is 'EventToCommand' (HashCode=6678752); target property is
'Command' (type 'ICommand')
我尝试使用相对源搜索祖先类型和元素名称,但是这两个选项都返回了更令人困惑的错误消息。显然我在这里遗漏了一些东西。
谢谢。
根据您问题中的错误消息,Button 的 DataContext 是 MainWindowViewModel
类型,但拥有 AddNode
命令的 class 称为 ManageSyncedAccountsViewModel
。
System.Windows.Data Error: 40 : BindingExpression path error: 'AddNode' property not found on 'object' ''MainWindowViewModel' (HashCode=-1718218621)'. BindingExpression:Path=DataContext.AddNode; DataItem='ManageSyncedAccountsView' (Name='ManageSyncControl'); target element is 'EventToCommand' (HashCode=6678752); target property is 'Command' (type 'ICommand')
尝试将 AddNode
放在按钮可以看到的 MainWindowViewModel
上。
我有一个带有下拉按钮的树视图。下拉按钮显示用于向树中添加节点的选项。当用户选择一个选项时,我希望命令被触发并由父用户控件中的命令处理。仅供参考,使用 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 Error: 40 : BindingExpression path error: 'AddNode' property not found on 'object' ''MainWindowViewModel' (HashCode=-1718218621)'. BindingExpression:Path=DataContext.AddNode; DataItem='ManageSyncedAccountsView' (Name='ManageSyncControl'); target element is 'EventToCommand' (HashCode=6678752); target property is 'Command' (type 'ICommand')
我尝试使用相对源搜索祖先类型和元素名称,但是这两个选项都返回了更令人困惑的错误消息。显然我在这里遗漏了一些东西。
谢谢。
根据您问题中的错误消息,Button 的 DataContext 是 MainWindowViewModel
类型,但拥有 AddNode
命令的 class 称为 ManageSyncedAccountsViewModel
。
System.Windows.Data Error: 40 : BindingExpression path error: 'AddNode' property not found on 'object' ''MainWindowViewModel' (HashCode=-1718218621)'. BindingExpression:Path=DataContext.AddNode; DataItem='ManageSyncedAccountsView' (Name='ManageSyncControl'); target element is 'EventToCommand' (HashCode=6678752); target property is 'Command' (type 'ICommand')
尝试将 AddNode
放在按钮可以看到的 MainWindowViewModel
上。