WPF / MVVM新手。我有一个类型为“MyData”的数据对象。其中一个属性是“MySubsetData”类型。
我在数据网格中显示“MyData”对象的集合。
<DataGrid ItemsSource="{Binding Path=MyDataCollection}">
<!-- Each row of the datagrid contains an item of type "MyData" -->
<DataGrid.Columns .../>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<local:MySubsetDataUserControl/>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
行详细信息应显示“MySubsetData”的内容。行详细信息的视图位于单独的用户控件中(此处:“MySubsetDataUserControl”)。
目前我没有为“MySubsetDataUserControl”设置视图模型,所以它从父的datagrid行继承了数据上下文。
<UserControl>
<!-- Namespace stuff not shown for simplicity -->
<Grid DataContext="{Binding Path=MySubsetData}">
<!-- Show the MySubsetData properties here -->
<!-- e.g. a textbox -->
<TextBox Text="{Binding Path=TextData, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</UserControl>
尽管这很有效,但我遇到了这种方法的几个问题:
所有业务逻辑都将位于用户控件父视图模型中,它根本不属于该模型。使视图模型比它需要的更加混乱。更不用说用户控件xaml中的命令绑定看起来也很丑陋。感觉不对劲。
由于可以同时显示更多行详细信息,因此无法将“MySubsetData”的属性绑定到视图模型中的可观察属性。即如果我更改代码中的属性(例如TextData),则更改将不会反映在视图中。我的解决方法是不改变属性“TextData”。相反,我更改了文本框Text属性的内容,而后者又会更新“TextData”属性。这感觉非常错误!
所以我想为我的用户控件使用另一个视图模型,但我不知道如何访问我的数据。
<UserControl.DataContext>
<local:UserControlViewModel/>
</UserControl.DataContext>
如何立即访问“MySubsetData”?
答案 0 :(得分:0)
假设你有一个这样的视图模型:
public class ViewModel
{
public IEnumerable<MyData> MyDataCollection{get; private set;}
}
哪里
public class MyData
{
public MySubsetData MySubsetData { get; }
}
包含DataGrid的视图将是
<UserControl.DataContext>
<local:ViewModel>
</UserControl.DataContext>
<DataGrid ItemsSource="{Binding Path=MyDataCollection}">
<DataGrid.Columns .../>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<!-- each row of the items control has an implicit DataContext of MyData -->
<!-- so bind the DataContext of the subset control to MySubsetData -->
<local:MySubsetDataUserControl DataContext={Binding MySubsetData}/>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
现在您的子集控件看起来像
<UserControl>
<Grid>
<TextBox Text="{Binding Path=TextData, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</UserControl>
重新阅读这个问题,也许我所做的就是以稍微不同的方式重复问题中的Xaml。
然而,各种类应该实现INotifyPropertyChanged,例如
public class MySubsetData : INotifyPropertyChanged
{
public string TextData
{
get{...}
set{...; OnPropertyChanged("TextData"); }
}
}
然后绑定到TextData属性的TextBox将反映代码中所做的更改。