【问题标题】:How to Get a Reference to a ViewModel如何获取对 ViewModel 的引用
【发布时间】:2013-07-22 20:20:12
【问题描述】:

所有,我有一个自定义的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

感谢您的宝贵时间。

【问题讨论】:

  • 你不能用this.DataContext as ResourceDataViewModel吗?
  • +1 表示评论。我刚刚意识到我可以直接从DataContext 投射 - 傻。非常感谢...如果您感到困扰,这可能是一个答案。感谢您的宝贵时间。

标签: c# wpf mvvm viewmodel


【解决方案1】:

获取DataContext 并将其转换为视图模型类型:

var viewModel = this.DataContext as ResourceDataViewModel

【讨论】:

    【解决方案2】:

    在您的应用上放置对它的静态引用,当创建 VM 时,将其引用放在静态上并根据需要访问它。

    【讨论】:

    • 这是标准方法吗?我发现很难持续与 MVVM 作战。这是我的第一个大型 MVVM,它正在杀死我!感谢您的回复...
    • 是的,我已经在 2 个 Silverlight 项目中完成了这项工作,并且最近在 Windows Phone 8 上发布到了应用商店。
    【解决方案3】:

    您问是否有更好的方法...根据我的经验,如果您发现自己在 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 旨在鼓励的所有“关注点分离”的好处......

    【讨论】:

      猜你喜欢
      • 2023-03-27
      • 1970-01-01
      • 2012-04-05
      • 2015-08-20
      • 1970-01-01
      • 1970-01-01
      • 2018-12-18
      • 1970-01-01
      • 2013-08-13
      相关资源
      最近更新 更多