所有,我有一个自定义的DataGridView
控件,它覆盖DataGidView
的OnItemsSourceChanged
事件。在这个事件中,我需要获得对相关ViewModel中的数据集的引用。代码为
public class ResourceDataGrid : DataGrid
{
protected override void OnItemsSourceChanged(
System.Collections.IEnumerable oldValue,
System.Collections.IEnumerable newValue)
{
if (Equals(newValue, oldValue))
return;
base.OnItemsSourceChanged(oldValue, newValue);
ResourceCore.ResourceManager manager = ResourceCore.ResourceManager.Instance();
ResourceDataViewModel resourceDataViewModel = ?? // How do I get my ResourceDataViewModel
List<string> l = manger.GetDataFor(resourceDataViewModel);
...
}
}
在标记的行上,我想知道如何获得对ResourceDataViewModel resourceDataViewModel
的引用。原因是我有多个选项卡,每个选项卡都包含一个数据网格和关联的ViewModel,ViewModel包含一些我需要[通过ResourceManager
]检索的数据(或者有其他更好的方法吗?)。
问题是,从上述事件中,我如何获得关联的ResourceDataViewModel
?
谢谢你抽出时间。
获取DataContext
并将其转换为视图模型类型:
var viewModel = this.DataContext as ResourceDataViewModel
在您的应用程序中放置对它的静态引用,当创建虚拟机时,将其引用放置在静态引用上,并根据需要访问它。
您询问是否有更好的方法。。。根据我的经验,如果你发现自己在WPF中对UI元素进行了子类化,那么通常会出现.
通过将整个选项卡控件数据绑定到视图模型,您可以避免嵌入业务逻辑(选择在网格中显示哪些数据)。
为了演示,这里有一个非常简单的例子。这是我的XAML,用于托管选项卡控件的窗口:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TabControl ItemsSource="{Binding Tabs}" SelectedItem="{Binding SelectedTab}">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding TabName}"></Setter>
</Style>
</TabControl.ItemContainerStyle>
<TabControl.ContentTemplate>
<DataTemplate>
<Grid>
<DataGrid ItemsSource="{Binding TabData}"></DataGrid>
</Grid>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
</Window>
我的窗口的数据上下文是TabsViewModel
(我使用的是可以在PRISM NuGet包中找到的NotificationObject
):
public class TabsViewModel: NotificationObject
{
public TabsViewModel()
{
Tabs = new[]
{
new TabViewModel("TAB1", "Data 1 Tab 1", "Data 2 Tab1"),
new TabViewModel("TAB2", "Data 1 Tab 2", "Data 2 Tab2"),
};
}
private TabViewModel _selectedTab;
public TabViewModel SelectedTab
{
get { return _selectedTab; }
set
{
if (Equals(value, _selectedTab)) return;
_selectedTab = value;
RaisePropertyChanged(() => SelectedTab);
}
}
public IEnumerable<TabViewModel> Tabs { get; set; }
}
public class TabViewModel
{
public TabViewModel(string tabName, params string[] data)
{
TabName = tabName;
TabData = data.Select(d => new RowData(){Property1 = d}).ToArray();
}
public string TabName { get; set; }
public RowData[] TabData { get; set; }
}
public class RowData
{
public string Property1 { get; set; }
}
这显然是一个过于简化的情况,但这意味着,如果有任何关于在每个选项卡中显示什么数据的业务逻辑,那么它可以位于其中一个视图模型中,而不是后面的代码中。这为您提供了MVVM旨在鼓励的所有"关注点分离"优势。。。