【问题标题】:Bind ViewModel to CustomControl将 ViewModel 绑定到 CustomControl
【发布时间】:2017-07-09 09:27:37
【问题描述】:

我的主窗口有一个侧边栏菜单。当单击菜单上的某个项目时,我将在 ContentControl 上呈现该项目的页面 (UserControl)。这是它的样子。

我的主视图模型

public MainViewModel()
{
    SystemMenu = new List<SystemMenuViewModel>();
    SystemMenu.Add(new SystemMenuViewModel("Dashboard", new Dashboard()));
    SystemMenu.Add(new SystemMenuViewModel("Appointments", new Dashboard()));
    SystemMenu.Add(new SystemMenuViewModel("Reports", new Reports()));
    SystemMenu.Add(new SystemMenuViewModel("Configuration", new Configuration()));
}

private string _windowTitle = GlobalVariables.WindowTitleDefault;
private string _currentPage = "Dashboard";

public string WindowTitle
{
    get { return _windowTitle; }
    set
    {
    _windowTitle = value;
    NotifyOfPropertyChange(() => WindowTitle);
    }
}

public string CurrentPage
{
    get { return _currentPage; }
    set
    {
    _currentPage = value;
    NotifyOfPropertyChange(() => CurrentPage);
    }
}

public List<SystemMenuViewModel> SystemMenu { get; set; }

我的 SystemMenuViewModel

private string _name;
private object _content;

public SystemMenuViewModel(string name, object content)
{
    _name = name;
    Content = content;
}

public string Name
{
    get { return _name; }
    set { this.MutateVerbose(ref _name, value, RaisePropertyChanged()); }
}

public object Content
{
    get { return _content; }
    set { this.MutateVerbose(ref _content, value, RaisePropertyChanged()); }
}

public event PropertyChangedEventHandler PropertyChanged;

private Action<PropertyChangedEventArgs> RaisePropertyChanged()
{
    return args => PropertyChanged?.Invoke(this, args);
}

渲染部分我的MainView

<ContentControl Content="{Binding ElementName=lstSystemMenu, Path=SelectedItem.Content}" />

我的主要问题是我只是在我的 MainView 上呈现内容,而没有实际调用或绑定它的 ViewModel。

我确信我的 MVVM 框架的实现有问题。请告诉我我哪里出了问题以及实现这一点的最佳方法是什么。

【问题讨论】:

  • Dashboard, Reports, Configuration... 是什么类型?它们是其他视图模型,还是 UI 元素?如果你想遵循 MVVM 模式,那么 viewmodel 不应该有任何 UI 元素。事实上,我认为系统菜单应该是视图层的一部分,或者至少是一个服务
  • 这些是视图 (UserControl)。您能帮我在单击菜单项时如何显示这些视图,而不像我目前那样做吗?哦,什么是服务?
  • 如果没有可靠地重现问题的良好minimal reproducible example 以及对问题的更准确描述,则无法编写此问题的正确答案。在您阅读介绍性信息(包括TourHelp Center 中有关Asking 的其他文章之前,请不要向 Stack Overflow 发布问题

标签: c# wpf mvvm viewmodel


【解决方案1】:

看看这个:https://msdn.microsoft.com/en-us/magazine/dd419663.aspx 找不到源zip,但是文章有很多代码示例。

您需要将 ContentControl 的 Content 属性绑定到 ViewModel/Model 对象,并使用 DataTemplates 根据数据上下文创建正确的页面。数据模板只需要存储在 ResourceDictionary 中,可以是 ContentControl 或一些上层控件(甚至是应用程序)。 DataTemplates 必须设置一个 DataType 才能工作。

此外,正如您问题的 cmets 中所建议的那样,视图模型不应具有对象类型的“内容”属性。看起来您的“内容”属性是一个视图对象或其他东西。如果没有您向我们展示更多代码,您将无法知道。 ViewModel 不应引用任何 View 对象。但 View 可以在代码隐藏或 XAML 中引用 ViewModel 类。

有两种方法可以绑定到“当前选择”。 要么使用视图列表中的“当前选定”信息(例如 SelectedItem),要么在 MainViewModel 中添加一个属性(例如:SelectedViewModel,然后将 ContentControl 绑定到这个属性。

【讨论】:

  • 感谢您为我指明正确的方向。我终于明白了。我对MVVM的理解显然很肤浅。很抱歉,如果这里的某些人特别难以理解我的问题@Peter Duniho 我想我会继续潜伏而不是直接问我自己的问题。
  • 没问题,MVVM 一开始可能很难做好。现在您的视图/视图模型问题已经排序,您将进入一些类属于何处的困境。模型还是视图模型?我是否使用实现 propertychange 的类似 viewmodel 类包装每个模型? SO上有很多答案。永远记住,MVVM 不仅适用于 WPF。一个好的 MVVM 项目可以有不同的视图实现(wpf、winform、uwp、控制台等),而无需更改一行共享视图模型代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-17
相关资源
最近更新 更多