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

时间:2018-02-17 15:40:54

标签: c# wpf caliburn.micro eventaggregator

我正在构建一个应用程序来帮助我学习C#,WPF和.NET。在我的应用程序中,我正在为修理订单加载多个CVS表的会计数据,每个CVS代表不同的计划。使用eventAggregator可以很好地工作。当用户按下"加载计划"按钮另一个窗口打开,其中有一个下拉框以选择计划名称,以及一个打开" OpenFileDialoge"框。用户选择单击"加载" trigers" _eventAggregator.PublishOnUIThread(SchedInfo);"。 ShellViewModel有一个HAndle,它接受Published" SchedInfo"并将数据传递给另一个读取文件的函数 - >构建每个RepairOrder并将它们添加到绑定到数据网格的修订订单的BindableCollection。这工作令人惊讶。我现在的问题是我想创建一个工作相同的第二个系统,但是读取一个excel文件并从中创建修复订单。我为要通过eventAggregator发送的excel消息创建了第二个ViewModel,view和class。我还创建了一个全新的" Handle(Message Class)"使用新的消息类型。但是我的新版本似乎没有将数据传回给" ShellViewModel"或者#34; ShellViewModel"不接受这些数据。有人可以看看我哪里出错了。

这是工作窗口的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();
        }
    }
}

这是ShellViewModel中正在运行的句柄:

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

以下是从工作加载程序传递到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;
        }
    }
}

现在我实际上从弹出的第一个ViewModel中复制并粘贴了窗口设计和大部分ViewModel。为新的Loader窗口创建了新的消息类,并更改了新窗口中的Sections以匹配新的消息类。

新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();
        }
    }
}

新Loader窗口句柄的代码:

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

用于NOT工作加载窗口的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;
        }

    }

从我读到的Caliburn.Micro实现的eventAggregator允许&#34; Handles&#34;使用多态,所以我觉得这两个句柄接受不同的Class对象,因为我应该使用它们。

作为一项测试,我在NOT工作句柄中注释了该行&#34; ReadFromCDKExport(ScheduleName,FileInfo);&#34;所以公共变量&#34; ScheduleName&#34;和&#34; FileInfo&#34;只是设置,然后我连接了一个测试按钮显示:

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

将弹出消息框,但消息中没有变量。

---------------------编辑基于Royi的答案----------------- ------------

我忘了将IHandle接口添加到Class。

1 个答案:

答案 0 :(得分:1)

eventAggregator使用接口IHandle来计算多态性

您可能忘了将CDKScheduleInfo接口的IHandle添加到ShellViewModel:)