简体   繁体   English

ShellViewModel处理eventAggregator Caliburn.Micro上的多个消息

[英]ShellViewModel Handling multiple messages on the eventAggregator, Caliburn.Micro

I am building an application to help me learn C#, WPF and .NET. 我正在构建一个应用程序来帮助我学习C#,WPF和.NET。 In my application, I am loading multiple CVS sheets of accounting data for repair orders, each CVS represents a different schedule. 在我的应用程序中,我正在加载维修订单的多个CVS会计数据表,每个CVS代表一个不同的时间表。 This is working great using eventAggregator. 使用eventAggregator可以很好地工作。 When the user presses the "load Schedule" button another window opens that has a drop down box to select the schedule name, and a button that opens a "OpenFileDialoge" box. 当用户按下“加载时间表”按钮时,将打开另一个窗口,该窗口具有用于选择时间表名称的下拉框,以及一个用于打开“ OpenFileDialoge”框的按钮。 After the user selects both clicking "Load" trigers "_eventAggregator.PublishOnUIThread(SchedInfo);". 用户选择两者后,单击“加载”触发器,然后选择“ _eventAggregator.PublishOnUIThread(SchedInfo);”。 The ShellViewModel has a HAndle that takes the Published "SchedInfo" and passes the data to another function that reads the file -> builds each RepairOrder and adds them to a BindableCollection of Repair Orders that is bound to a datagrid. ShellViewModel具有处理已发布的“ SchedInfo”的HAndle,并将数据传递给另一个函数,该函数读取文件->构建每个RepairOrder,并将它们添加到绑定到数据网格的Repair Orders的BindableCollection中。 This is working amazingly. 这是惊人的工作。 My issue now is that I want to create a second system that works the same but reads an excel file and creates the repair orders from this. 现在的问题是,我想创建另一个工作原理相同的系统,但读取一个excel文件并从中创建维修订单。 I created a second ViewModel, view, and class for the excel message to be sent across the eventAggregator. 我创建了第二个ViewModel,视图和类,用于在eventAggregator中发送的excel消息。 I also created a completely new "Handle(Message Class)" to work with the new message type. 我还创建了一个全新的“句柄(消息类)”以使用新的消息类型。 However my new version does not seem to be passing the data back to the "ShellViewModel" or the "ShellViewModel" is not accepting the data. 但是,我的新版本似乎没有将数据传递回“ ShellViewModel”,或者“ ShellViewModel”不接受数据。 Can someone please see where I went wrong. 有人可以看看我哪里出错了。

This is the ViewModel code for the working window: 这是工作窗口的ViewModel代码:

namespace ScheduleReview.ViewModels
{
    class SelSchedViewModel : Screen
    {
        /* System level properties */
        private readonly IEventAggregator _eventAggregator;
        List<string> folder = new List<string>();


        /* Class level properties*/

        private BindableCollection<string> _cmboBoxOptions = new BindableCollection<string>() { "Navistar", "Cummins", "Misc", "Kenworth", "Mack/Volvo" };

        public BindableCollection<string> CmboBoxOption
        {
            get { return _cmboBoxOptions; }
            set {
                _cmboBoxOptions = value;
                NotifyOfPropertyChange(() => CmboBoxOption);
            }
        }

        private string _scheduleName;

        public string ScheduleName
        {
            get { return _scheduleName; }
            set {
                _scheduleName = value;
                NotifyOfPropertyChange(() => ScheduleName);
            }
        }

        private string _fileLocation;

        public string FileLocation
        {
            get { return _fileLocation; }
            set {
                _fileLocation = value;
                NotifyOfPropertyChange(() => FileLocation);

            }
        }

        private string _fullLocation;

        public string FullLocation
        {
            get { return _fullLocation; }
            set {
                _fullLocation = value;
                NotifyOfPropertyChange(() => FullLocation);
            }
        }


        /* Constructor */
        public SelSchedViewModel(IEventAggregator eventAggregator)
        {
            this._eventAggregator = eventAggregator;
        }

        //Needs work still
        public void LoadSchedule()
        {
            if (folder.Contains(FileLocation))
            {
                MessageBox.Show("This file has already been used ", "Loaded File", MessageBoxButton.OK, MessageBoxImage.Error);
                ScheduleName = null;
                FileLocation = null;
                return;
            }

            //Create and set the class to return from
            //string file location and schedule number
            if(ScheduleName == null || FileLocation == null)
                {
                    MessageBox.Show("Enter the schedule name and choose a file location!", "Invalid Selections", MessageBoxButton.OK,MessageBoxImage.Error);
                }
                else
                {
                    ScheduleInfo SchedInfo = new ScheduleInfo(ScheduleName, FullLocation);
                    _eventAggregator.PublishOnUIThread(SchedInfo);
                    folder.Add(FileLocation);

                    ScheduleName = null;
                    FileLocation = null;

                }
            }

        public void SelectFile()
        {

            //Open the file selector box
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = Environment.SpecialFolder.MyDocuments.ToString();
            ofd.DefaultExt = ".csv";
            ofd.Filter = "CSV Documents (.CSV)|*.csv";

            Nullable<bool> result = ofd.ShowDialog();
            if (result == true)
            {
                FullLocation = ofd.FileName;
                char delimiter = '\\';
                string[] NameArray = ofd.FileName.Split(delimiter);
                FileLocation = NameArray[NameArray.Count() - 1];
            }
        }

        //Closes Window
        public void Close()
        {
            TryClose();
        }
    }
}

This is the Handle in ShellViewModel that is working: 这是正在运行的ShellViewModel中的Handle:

public void Handle(ScheduleInfo message)
        {
            ScheduleName = message.ScheduleName;
            FileInfo = message.FileLocation;
            LoadSchedule(ScheduleName, FileInfo);
        }

Here is the code for the POCO class that is passed from the working loader to the ShellViewModel: 这是从工作加载器传递到ShellViewModel的POCO类的代码:

namespace ScheduleReview.Models
{
    public class ScheduleInfo
    {
        public string ScheduleName
        {
            get;
            private set;
        }

        public string FileLocation
        {
            get;
            private set;
        }

        public ScheduleInfo(string SN, string FL)
        {
            ScheduleName = SN;
            FileLocation = FL;
        }
    }
}

Now I actually copy and pasted the window design and most of the ViewModel from the first ViewModel that pops up. 现在,我实际上从弹出的第一个ViewModel复制并粘贴了窗口设计和大多数ViewModel。 Created and new message class for the new Loader window and changed the Sections in the new window to match the new message class. 为新的Loader窗口创建了新的消息类,并在新窗口中更改了Sections以匹配新的消息类。

The code for the ViewModel of the new Loader is: 新的Loader的ViewModel的代码是:

namespace ScheduleReview.ViewModels
{
    class SelCDKSchedViewModel : Screen
    {
        /* System level properties */
        private readonly IEventAggregator _eventAggregator;
        List<string> folder = new List<string>();


        /* Class level properties*/

        private BindableCollection<string> _cmboBoxOptions = new BindableCollection<string>() { "Navistar", "Cummins", "Misc", "Kenworth", "Mack/Volvo" };

        public BindableCollection<string> CmboBoxOption
        {
            get { return _cmboBoxOptions; }
            set
            {
                _cmboBoxOptions = value;
                NotifyOfPropertyChange(() => CmboBoxOption);
            }
        }

        private string _scheduleName;

        public string ScheduleName
        {
            get { return _scheduleName; }
            set
            {
                _scheduleName = value;
                NotifyOfPropertyChange(() => ScheduleName);
            }
        }

        private string _fileLocation;

        public string FileLocation
        {
            get { return _fileLocation; }
            set
            {
                _fileLocation = value;
                NotifyOfPropertyChange(() => FileLocation);

            }
        }

        private string _fullLocation;

        public string FullLocation
        {
            get { return _fullLocation; }
            set
            {
                _fullLocation = value;
                NotifyOfPropertyChange(() => FullLocation);
            }
        }


        /* Constructor */
        public SelCDKSchedViewModel(IEventAggregator eventAggregator)
        {
            this._eventAggregator = eventAggregator;
        }

        //Needs work still
        public void LoadSchedule()
        {
            if (folder.Contains(FileLocation))
            {
                MessageBox.Show("This file has already been used ", "Loaded File", MessageBoxButton.OK, MessageBoxImage.Error);
                ScheduleName = null;
                FileLocation = null;
                return;
            }

            //Create and set the class to return from
            //string file location and schedule number
            if (ScheduleName == null || FileLocation == null)
            {
                MessageBox.Show("Enter the schedule name and choose a file location!", "Invalid Selections", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else
            {
                CDKScheduleInfo CDKSchedInfo = new CDKScheduleInfo(ScheduleName, FullLocation);
                _eventAggregator.PublishOnUIThread(CDKSchedInfo);
                folder.Add(FileLocation);

                ScheduleName = null;
                FileLocation = null;

            }
        }

        public void SelectFile()
        {

            //Open the file selector box
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = Environment.SpecialFolder.MyDocuments.ToString();
            ofd.DefaultExt = ".xlsx";
            ofd.Filter = "XLSX Documents (.XLSX)|*.xlsx";

            Nullable<bool> result = ofd.ShowDialog();
            if (result == true)
            {
                FullLocation = ofd.FileName;
                char delimiter = '\\';
                string[] NameArray = ofd.FileName.Split(delimiter);
                FileLocation = NameArray[NameArray.Count() - 1];
            }
        }

        //Closes Window
        public void Close()
        {
            TryClose();
        }
    }
}

Code for the Handle of the new Loader window: 新的“加载程序”窗口的句柄代码:

public void Handle(CDKScheduleInfo message)
        {
            ScheduleName = message.ScheduleName;
            FileInfo = message.FileLocation;
            ReadFromCDKExport(ScheduleName, FileInfo);
        }

Poco class for the NOT working loading window. 不工作加载窗口的Poco类。

class CDKScheduleInfo
    {
        public string ScheduleName
        {
            get;
            private set;
        }

        public string FileLocation
        {
            get;
            private set;
        }

        public CDKScheduleInfo(string SN, string FL)
        {
            ScheduleName = SN;
            FileLocation = FL;
        }

    }

From what I read Caliburn.Micro's implementation of the eventAggregator allows the "Handles" to use polymorphism, so I felt the two handles accepting different Class objects as I have them should work. 从我读到的内容来看,Caliburn.Micro的eventAggregator的实现允许“句柄”使用多态性,因此我觉得这两个接受不同Class类对象的句柄应该起作用。

As a test I commented out the line in the NOT working handle "ReadFromCDKExport(ScheduleName, FileInfo);" 作为测试,我在NOT工作句柄中注释了这一行“ ReadFromCDKExport(ScheduleName,FileInfo);”。 so the public variables "ScheduleName" and "FileInfo" would just get set, then I wired a test button to show: 因此只需设置公共变量“ ScheduleName”和“ FileInfo”,然后连接一个测试按钮以显示:

MessageBox.Show(ScheduleName + Environment.newline + FileInfo, "Test", MessageBoxButton.OK);

The message box would pop up but there was no variables in the message. 消息框将弹出,但是消息中没有变量。

---------------------EDIT Based on Royi's Answer----------------------------- ---------------------根据Royi的答案进行编辑------------------------ -----

I forgot to add the IHandle interface to the Class. 我忘记将IHandle接口添加到Class中。

The eventAggregator uses the interface IHandle to figure out the polymorphism, eventAggregator使用接口IHandle找出多态性,

You probably forgot to add the IHandle for CDKScheduleInfo interface to ShellViewModel :) 您可能忘记了将IHandle for CDKScheduleInfo接口添加到ShellViewModel :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM