如何获取对ViewModel的引用

本文关键字:ViewModel 引用 获取 何获取 | 更新日期: 2023-09-27 18:24:13

所有,我有一个自定义的DataGridView控件,它覆盖DataGidViewOnItemsSourceChanged事件。在这个事件中,我需要获得对相关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

谢谢你抽出时间。

如何获取对ViewModel的引用

获取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旨在鼓励的所有"关注点分离"优势。。。