【问题标题】:Sharing Object between Views & ViewModels in MVVM在 MVVM 中的视图和视图模型之间共享对象
【发布时间】:2017-01-14 23:35:44
【问题描述】:

我是 WPF + MVVM 的新手,在处理视图模型时遇到了麻烦。

我有一个名为 FSystem 的对象,其中包含许多从 XML 填充的列表。

public class FSystem : ObservableObject
{
    public List<FUser> _userList;
    public List<FZone> _zoneList;
    public List<FSource> _sourceList;

    public string _projectName { get; set; }
    private string _projectVersion { get; set; }
    private string _processorIp { get; set; }

    private bool _isMultiLingualModeOn { get; set; }

    private int _systemIncludeLighting { get; set; }
    private int _systemIncludeWindowsTreatments { get; set; }
    private int _systemIncludeSip { get; set; }
    private int _systemIncludeCamaras { get; set; }

    public FSystem()
    {
        UserList = new List<FUser>();
    }
}

这是当用户将 XML 加载到应用程序时调用的 XMLParser。

public static class XMLParsers
{
    public static FSystem ParseByXDocument(string xmlPath)
    {
        var fSystem = new FSystem();

        XDocument doc = XDocument.Load(xmlPath);

        XElement fSystemElement = doc.Element("FSystem");

        if (fSystemElement != null)
        {
            fSystem.ProjectName = fSystemElement.Element("ProjectName").Value;
            fSystem.ProjectVersion = fSystemElement.Element("ProjectVersion").Value;
            fSystem.ProcessorIp = fSystemElement.Element("ProcessorIP").Value;
            fSystem.ProcessorFilePath = fSystemElement.Element("ProcessorFilePath").Value;
            fSystem.SystemIncludeLighting = Convert.ToInt16(fSystemElement.Element("SystemIncludeLighting").Value);
            fSystem.SystemIncludeSip = Convert.ToInt16(fSystemElement.Element("SystemIncludeLighting").Value);
            fSystem.SystemIncludeCamaras = Convert.ToInt16(fSystemElement.Element("SystemIncludeCameras").Value);
        }

        fSystem.UserList = (from user in doc.Descendants("FUser")
                                 select new FUser()
                                 {
                                     Id = user.Element("Id").Value,
                                     Name = user.Element("Name").Value,
                                     Icon = user.Element("IconColour").Value,
                                     Pin = user.Element("UserPin").Value,
                                     IsPinEnabled = Convert.ToBoolean(Convert.ToInt16(user.Element("UserPinEnabled").Value)),
                                     ListIndex = user.Element("ListIndex").Value
                                 }).ToList();

        return fSystem;
    }
}

这是下面的 MainViewModel,它包含加载 XML 的命令和我希望在其他视图模型中使用的属性 FSystem。

public class MainViewModel : ViewModel 
{
    private Fystem fSystem;
    public FSystem FSystem
    {
        get { return fSystem; }
        private set
        {
            fSystem = value;
            NotifyPropertyChanged("FSystem");
        }
    }

    public MainViewModel()
    {
        InitiateState();
        WireCommands();
    }

    private void InitiateState()
    {
        FSystem = new FSystem();
    }

    private void WireCommands()
    {
        XDocumentLoadCommand = new RelayCommand(XDocumentLoad) {IsEnabled = true};

        ClearDataCommand = new RelayCommand(ClearData) {IsEnabled = true};
    }
public RelayCommand XDocumentLoadCommand { get; private set; }
    private void XDocumentLoad()
    {
        var openDlg = new OpenFileDialog
        {
            Title = "Open .FAS",
            DefaultExt = ".fas",
            Filter = "F System Files (*.fas)|*.fas",
            Multiselect = false
        };

        bool? result = openDlg.ShowDialog() == DialogResult.OK;
        if (result != true) return;

        FSystem = XMLParsers.ParseByXDocument(openDlg.FileName);
    }

该应用程序基本上允许用户更改不同的对象(FUser、FZone、FSource 等)。我的想法是用户将加载 XML,然后能够在不同的视图上编辑不同的列表对象。

在 MVVM 中解决此问题的正确方法是什么?

我计划(希望)让 User、Zone 和 Source 视图显示 Datagrids,这些 Datagrids 填充了来自模型的各自数据。

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

    为您创建特定的视图模型,并使用依赖注入将相关数据传递给它们(这个列表或那个列表)。

    这样,视图模型不需要了解其他内容,您可以轻松地对其进行模拟以进行测试,并在设计器上查看虚拟数据。

    将粘贴复制到 Linqpad 以作为最简单的示例。两个模拟视图模型都具有依赖关系(在我们的例子中是 i)。您可以只传递您的列表:

    void Main()
    {
        int someInt = 5;
        int anotherInt = 7;
    
        VM vm1 = new VM(someInt);
        VM vm2 = new VM(anotherInt);
    
        vm1.RevealI();
        vm2.RevealI();
    }
    
    public class VM{
        private int _i;
    
        public VM(int i)
        {
            _i = i; 
        }
    
        public void RevealI() { Console.WriteLine("value of i is: " + _i); }
    }
    

    除此之外,还有更多项目:

    【讨论】:

    • 嗨,Noctis,感谢您的回复。很抱歉成为那个人,但您能否通过链接指南或模拟 sn-p 为我指明正确的方向?我以前没有使用过依赖注入,所以我真的不知道什么与我在做什么相关。
    • 是的,我有:)。我一直在阅读您留下的依赖注入项。根据我收集的信息,我应该将 FSystem 传递到我的 ViewModels/UserControls 中,以便可以使用它们。我只是在考虑如果 FSystem 为空(如果他们正在从头构建/创建 XML),我如何允许用户能够打开其他视图。
    • 如果为空,要么不打开视图,要么让他们知道他们没有数据。更好的是,传递一个新铸造的对象,他们可以手动填充它......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多