C# 如何从子viewmodel绑定到父viewmodel中的事件
我目前正在遵循设置带有复选框的树视图的指南。在我的代码中,树“FooViewModel”在我的MainViewModel中启动,并作为ItemsSource绑定到TreeView。我希望能够订阅MainViewModel中的某个事件,该事件将在选中或取消选中某些内容时触发。这样我就可以遍历“FooViewModel”并检查哪些节点的IsChecked=True。如何创建此事件绑定 这是我的代码:C# 如何从子viewmodel绑定到父viewmodel中的事件,c#,wpf,xaml,mvvm,treeview,C#,Wpf,Xaml,Mvvm,Treeview,我目前正在遵循设置带有复选框的树视图的指南。在我的代码中,树“FooViewModel”在我的MainViewModel中启动,并作为ItemsSource绑定到TreeView。我希望能够订阅MainViewModel中的某个事件,该事件将在选中或取消选中某些内容时触发。这样我就可以遍历“FooViewModel”并检查哪些节点的IsChecked=True。如何创建此事件绑定 这是我的代码: <Style x:Key="TreeViewItemStyle" TargetType="Tr
<Style x:Key="TreeViewItemStyle" TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="False" />
<Setter Property="IsSelected" Value="{Binding IsInitiallySelected, Mode=OneTime}" />
<Setter Property="KeyboardNavigation.AcceptsReturn" Value="True" />
<Setter Property="xn:VirtualToggleButton.IsVirtualToggleButton" Value="True" />
<Setter Property="xn:VirtualToggleButton.IsChecked" Value="{Binding IsChecked}" />
<Setter Property="Focusable" Value="False" />
</Style>
<xn:TreeView ItemsSource="{Binding CollectionFooViewModel}" ItemContainerStyle="{StaticResource TreeViewItemStyle}">
<xn:TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children, Mode=OneTime}">
<StackPanel Orientation="Horizontal">
<CheckBox Focusable="False" IsChecked="{Binding IsChecked}" VerticalAlignment="Center"/>
<ContentPresenter Content="{Binding Name, Mode=OneTime}" Margin="2,0"/>
</StackPanel>
</HierarchicalDataTemplate>
</xn:TreeView.ItemTemplate>
</xn:TreeView>
我想如果有一种方法可以将“IsChecked”绑定到两个属性(一个在FooViewModel中,另一个在MainViewModel中),我会有我的答案。尝试在模型的setter中添加“OnPropertyEventChanged”方法调用,下面是我的一个示例:
实现这一点的方法很多。一种是某种发布/订阅(消息传递)实现,或者可能只是一群
操作委托?类似于
主窗口
<Window x:Class="WpfApplication1.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="300"
Width="250">
<TreeView ItemsSource="{Binding CollectionFooViewModel}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children, Mode=OneTime}">
<StackPanel Orientation="Horizontal">
<CheckBox Focusable="False"
IsChecked="{Binding IsChecked}"
VerticalAlignment="Center"/>
<ContentPresenter Content="{Binding Name, Mode=OneTime}"
Margin="2,0"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Window>
DataContext
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
Action<MyItem> action = item => Console.WriteLine(@"MyItem was clicked");
CollectionFooViewModel = new ObservableCollection<MyItem>()
{
new MyItem()
{
Name = "MyItem1",
Children = new List<MyItem>()
{
new MyItem()
{
Name = "MySubItem1",
IsChecked = false,
Action = item => Console.WriteLine(@"{0} invoked action", item.Name)
},
new MyItem()
{
Name = "MySubItem2",
IsChecked = true,
Action = item => Console.WriteLine(@"{0} state is {1} ", item.Name, item.IsChecked)
},
},
Action = action
}
};
}
public ObservableCollection<MyItem> CollectionFooViewModel { get; set; }
}
public class MyItem : ViewModelBase
{
private bool _isChecked;
public string Name { get; set; }
public bool IsChecked
{
get { return _isChecked; }
set
{
_isChecked = value;
if (Action != null)
Action.BeginInvoke(this, null, null);
}
}
public IEnumerable<MyItem> Children { get; set; }
public Action<MyItem> Action { get; set; }
}
public类MainViewModel:ViewModelBase
{
公共主视图模型()
{
Action=item=>Console.WriteLine(@“MyItem已单击”);
CollectionFooViewModel=新的ObservableCollection()
{
新的MyItem()
{
Name=“MyItem1”,
Children=新列表()
{
新的MyItem()
{
Name=“MySubItem1”,
IsChecked=false,
Action=item=>Console.WriteLine(@“{0}调用的操作”,item.Name)
},
新的MyItem()
{
Name=“MySubItem2”,
IsChecked=true,
Action=item=>Console.WriteLine(@{0}状态为{1}),item.Name,item.IsChecked)
},
},
行动
}
};
}
公共ObservableCollection CollectionFooViewModel{get;set;}
}
公共类MyItem:ViewModelBase
{
检查私人住宅;
公共字符串名称{get;set;}
公共场所被检查
{
获取{return\u已检查;}
设置
{
_isChecked=值;
如果(操作!=null)
Action.BeginInvoke(this,null,null);
}
}
公共IEnumerable子项{get;set;}
公共操作动作{get;set;}
}
这给了你以下信息
…并在按顺序单击时将其输出到控制台
已单击MyItem
MySubItem1调用的操作
MySubItem2状态为False
当然,在您的情况下,您可能希望传递具体的方法进行委派。我有这样的方法,但由于我只能在检查顶部节点时订阅propertychange事件,而不能订阅子节点,因此这并不能解决我的问题。如果您要为所使用的样式和模板添加代码,或者避免在您给出的代码中使用它们,方法是在一个更简单的、不太“设计”的代码中创建此场景。它可以帮助我们了解您试图实现的目标,并提出解决方案