此示例是我的要求的简化版本。如果我能解决这个问题,那么剩下的就很简单了(我希望)。假设我有一个
的类层次结构A类:
Name
List <Class B>
B类:
Name
List <Class C>
C类:
Name
每个类都有一个单独的视图,视图模型和模型。我的主视图将每个视图放在DockPanel中。每个类的视图都是一个DataGrid,它只是放置每个列表的名称。当我点击A类的名字时,它会显示下面B类的名字。当我单击B类的名称时,它会显示C类的名称。所以基本上3个用户控件都是在我的MainView中的dockpanel上显示的所有DataGrid控件。
我仍然在MVVM中找到自己的脚,我不确定这是否是最好的方法。我想要的方法是每个视图模型都有一个名为SelectedItem的属性绑定到其视图中DataGrid中的SelectedItem。设置该属性后,将设置另一个名为ChildViewModel的属性。但我不知道如何在我的MainView和每个控件中设置它。如何将控件绑定到它的父datacontext,以及如何将项源绑定到父项中的选定项?
答案 0 :(得分:0)
我将有一个ViewModel,它是Window / UserControl / etc的DataContext,这些控件都被分组。然后设置ClassA加3个SelectedItem属性的集合。在SelectedItem属性中,您需要将下一个设置为null或默认值。
private ObservableCollection<ClassA> _CollectionOfA;
public ObservableCollection<ClassA> CollectionOfA
{
get { return _CollectionOfA; }
set
{
if (value == _CollectionOfA)
return;
_CollectionOfA = value;
RaisePropertyChanged(() => CollectionOfA);
}
}
private ClassA _SelectedClassA;
public ClassA SelectedClassA
{
get { return _SelectedClassA; }
set
{
if (value == _SelectedClassA)
return;
_SelectedClassA = value;
SelectedClassB = null; //Or default this to first item in the list, etc.
RaisePropertyChanged(() => SelectedClassA);
}
}
//Repeat SelectedClassA pattern for SelectedClassB/SelectedClassC
public ClassB SelectedClassB { get; set; }
public ClassC SelectedClassC { get; set; }
然后在绑定中,您将使用SelectedClassA.CollectionOfClassB属性作为第二个DataGrid的ItemsSource等。
<DataGrid ItemsSource="{Binding CollectionOfClassA}" SelectedItem="{Binding SelectedClassA}">
//columns defined here
</DataGrid>
<DataGrid ItemsSource="{Binding SelectedClassA.CollectionOfClassB}" SelectedItem="{Binding SelectedClassB}">
//columns defined here
</DataGrid>
<DataGrid ItemsSource="{Binding SelectedClassB.CollectionOfClassC}" SelectedItem="{Binding SelectedClassC}">
//columns defined here
</DataGrid>
修改强> 第一个选项是KISS方法。另一个选择是使用MVVM Light之类的东西,通过它的weak event pattern类实现messenger。在第二个ViewModel的构造函数中,您注册以侦听第一个ViewModel中SelectedItem的更改。在第一个ViewModel的setter中,您发送一条SelectedItem已更改的消息。下面是ClassBViewModel的示例(ClassAViewModel只需要其SelectedClassA setter来发送消息,构造函数中没有侦听器。而ClassCViewModel会监听但不需要发送)。
public class ClassBViewModel : ViewModelBase
{
private ClassA _SelectedClassA;
public ClassA SelectedClassA
{
get { return _SelectedClassA; }
set
{
if (value == _SelectedClassA)
return;
_SelectedClassA = value;
RaisePropertyChanged(() => SelectedClassA);
}
}
private ClassB _SelectedClassB;
public ClassB SelectedClassB
{
get { return _SelectedClassB; }
set
{
if (value == _SelectedClassB)
return;
var oldValue = _SelectedClassB;
_SelectedClassB = value;
Messenger.Default.Send(new PropertyChangedMessage<ClassB>(oldValue, value, "SelectedClassB"));
RaisePropertyChanged(() => SelectedClassB);
}
}
public ClassBViewModel()
{
Messenger.Default.Register<PropertyChangedMessage<ClassA>>(this, (message) => SelectedClassA = message.NewValue);
}
}
DataGrid的ClassBView xaml看起来仍然相同:
<DataGrid ItemsSource="{Binding SelectedClassA.CollectionOfClassB}" SelectedItem="{Binding SelectedClassB}">
//columns defined here
</DataGrid>