我正在构建一个应用程序来帮助我学习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。
答案 0 :(得分:1)
eventAggregator使用接口IHandle来计算多态性
您可能忘了将CDKScheduleInfo接口的IHandle添加到ShellViewModel:)