如何使用 MVVM 和 Caliburn Micro 在多个 ViewModel 中使用模型中的数据

Posted

技术标签:

【中文标题】如何使用 MVVM 和 Caliburn Micro 在多个 ViewModel 中使用模型中的数据【英文标题】:How do I use data from a Model in multiple ViewModels, using MVVM and Caliburn Micro 【发布时间】:2020-11-13 02:58:55 【问题描述】:

我真的需要你的帮助来为我澄清一些事情;我无法在互联网上找到答案,即使我的问题经常被问到;它从来没有显示人们对接受的答案的意思。

我的问题是这样的:

我有一个 ShellViewModel;在这个 ShellViewModel 上,我想显示一个 PageTitle。然而;我希望这个 PageTitle 显示在 另一个 ViewModel 中;显示在 ShellViewModel 内部

在 VB.Net 中,我只需创建一个公共字符串 PageTitle 并从其他表单中引用它(例如 textbox.text = MainForm.PageTitle);但这似乎在 C#/WPF/MVVM 中不起作用..

如何创建一个可以从多个位置设置和检索的“全局变量”;而所有人都拥有相同的信息?

我尝试了一些东西;这有效,但仅适用于 ShellViewModel(其他 ViewModel 无法访问)

这部分只工作一次;但我仍然有在这个 ViewModel 上创建一个新实例的问题;所以任何其他 ViewModel 仍然会得到另一个数据..

我真的,真的很困惑如何做这样一件卑微的工作......谁愿意帮助一个迷失的灵魂?

================================[编辑]============= ========================== 好吧..所以我有一些有用的东西; 有人可以验证这是否是正确的方法吗?


namespace ServiceTools.UserInterface.Models

    public class PageTitleModel

    
        public static string Title  get; set; 
        public PageTitleModel()
        
            Title = "Something something, You dont see me actually.. right?!";
        
    


public class ShellViewModel : Conductor<object> 
    
    //Property for the Page title
    public string PageTitle
    
        get  return PageTitleModel.Title; 
        set
        
            PageTitleModel.Title = value;
            NotifyOfPropertyChange(() => PageTitle);
        
    

    public ShellViewModel()
    
        PageTitleModel.Title = "Hello World";
        // Set the Application Titlebar and DisplayName
        SetTitles(PageTitleModel.Title);
    
    
    public void SetTitles (string Title)
    
        //Title of the window
        this.DisplayName = Title;
        PageTitle = Title;
    


namespace ServiceTools.UserInterface.ViewModels

    public class OrderRegistrationViewModel : Screen
    

        //private string PageTitle = PageTitleModel.Title;
        //Property for the Page title
        public string PageTitle
        
            get  return PageTitleModel.Title; 
            set
            
                PageTitleModel.Title = value;
                NotifyOfPropertyChange(() => PageTitle);
            
        
    

这似乎在两个视图之间同步标题... 有人可以验证这是否是要走的路吗?

【问题讨论】:

A Model 是您想以这种方式调用的any 类。您可以拥有一个可能从数据库加载的 Customer 类,并将其显示在任何接受 Customer 的屏幕或 ViewModel 上 PageTitle 是一个属性,而不是一个对象。您在 VB 中所做的是从一种形式到另一种形式的硬代码访问,这是一种非常糟糕的做法。无论如何,VB和C#之间没有区别。在这两种语言中,不同的表单和不同的元素可以绑定到相同的对象属性或资源 @PanagiotisKanavos 我知道这是不好的做法;这就是为什么我试图“转变”自己远离它;但我无法弄清楚如何.. 在这两种情况下,只需将相同的对象传递给所有表单。或者使用Customer 属性并在显示该属性之前设置它。 hmhm.. 听起来很简单;但是我无法将该句子转换为工作代码..因此为什么我首先问这个问题:)(对不起,我真的无法做这个看似简单的事情,这让我很害怕) 【参考方案1】:

每个 Screen (ViewModel) 在使用 Screen 作为其继承类型时都已具有此属性。他们有一个名为DisplayName 的内置属性,当然你可以创建一个屏幕类型的BaseViewModel 并重新创建***,如果你愿意的话。这是在Screen 中实现的IScreen(具有IHaveDisplayName)接口的结果。

//C#//
public class BaseViewModel : Screen 

  private string _screenTitle; 
  public string ScreenTitle 
        get => _screenTitle;
        set 
             _screenTitle = value;
             NotifyOfPropertyChange();
        
 
   



//C#//
public class OrderRegistrationViewModel : BaseViewModel 
   public OrderRegistrationViewModel()
       DisplayName = "Order Registration";
       ScreenTitle = "BumbleBee Tuna";
   

   


<!--XAML -->
<UserControl>
    <!-- Bound by convention via DataContext automagically by CM in the underlying framework -->
   <TextBlock x:Name="DisplayName" />  
   <TextBlock x:Name="ScreenTitle" />
</UserControl>

【讨论】:

你好 mvermef;谢谢你的回答。这个问题是关于通用变量的;我选择 pagetitle 作为我的测试属性,但这也可以是其他一些属性。我相信你的答案不再适合这个问题?

以上是关于如何使用 MVVM 和 Caliburn Micro 在多个 ViewModel 中使用模型中的数据的主要内容,如果未能解决你的问题,请参考以下文章

C# WPF MVVM开发框架Caliburn.Micro 名称Transformer⑩①

MVVM框架 -- Caliburn.Micro 系列文章

从Caliburn.Micro,WPF,MVVM中的另一个窗口获取信息

关于使用 Caliburn.Micro MVVM WPF 进行视图导航的建议

C# WPF MVVM开发框架Caliburn.Micro入门介绍①

C# WPF MVVM开发框架Caliburn.Micro自定义引导程序④