gpt4 book ai didi

c# - 哪一层应该包含 ICommand?

转载 作者:行者123 更新时间:2023-11-30 19:25:16 26 4
gpt4 key购买 nike

在 WPF 中,我有一个名为 Malfunctions 的 ViewModel 类,它有一个 PartMalfunctions 的 ObservableCollection。通常,ObservableCollection 中有 10 到 15 个 PartMalfunction 对象;有多少取决于超出该问题范围的其他参数。

我有一些 xaml,它有一个绑定(bind)到这个 ObservableCollection 的 DataGrid。在 DataGrid 中,我显示了 PartMalfuction 的各种属性(即描述、名称等),并且我有一个用户可以单击的开始计时器按钮。 Start timer 按钮绑定(bind)到 PartMalfunction Model 类中的 ICommand StopwatchCmd(您可以在下面的代码中看到所有这些)。

这是我的问题:我的 StopwatchCmd 是否在错误的层中(即 - 它是否属于故障 ViewModel)?我真的很挣扎,并试图在我的自己的,但我一直在碰壁,可以这么说,因为模型类中的 StopwatchCmd 工作得很好!我的意思是它能够在那里执行并执行它需要的任何业务规则,并且只与它触发的对象实例进行交互。如果我将它放在 ViewModel 中,那么我似乎必须做更多的工作才能让它完成它已经在做的事情。

请注意,我从故障 View 模型中遗漏了一些代码,因为它与这个问题无关。以下是故障 ViewModel 的代码。

public class Malfunctions : ViewModelBase {
public ObservableCollection<Model.PartMalfunction> AllPartMalfunctions {
get;
private set;
}
}

PartMalfunction 的模型类看起来像这样:

public class PartMalfunction : INotifyPropertyChanged {
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

private void OnPropertyChanged(string propertyName) {
if (PropertyChanged != null) {
PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}

private int _seconds;
private string _stopwatchText = string.Empty;
private bool _isStopwatchInProgress = false;
System.Windows.Threading.DispatcherTimer _timer = new System.Windows.Threading.DispatcherTimer();
RelayCommand _stopwatchCmd;

public ICommand StopwatchCmd {
get {
if (_stopwatchCmd == null)
_stopwatchCmd = new RelayCommand(param => this.StopwatchClick());
return _stopwatchCmd;
}
}
public bool IsStopwatchInProgress {
get {
return _isStopwatchInProgress;
}
set {
_isStopwatchInProgress = value;
OnPropertyChanged("IsStopwatchInProgress");
}
}
public string StopwatchText {
get {
return _stopwatchText;
}
set {
_stopwatchText = value;
OnPropertyChanged("StopwatchText");
}
}
private void StopwatchClick() {

if (!this.IsStopwatchInProgress) {
// Start the timer
_seconds = 0;

// Will immediately update the timer text to "00:00:00"
this.StopwatchText = GetElapsed();

_timer.Tick += DispatcherTimer_Tick;
_timer.Interval = new TimeSpan(0, 0, 1); // Ticks every second
_timer.Start();

this.IsStopwatchInProgress = true;
}
else {
// Stop the timer
_timer.Stop();
_timer.Tick -= DispatcherTimer_Tick;
_seconds = 0;

this.IsStopwatchInProgress = false;
}
}
private void DispatcherTimer_Tick(object sender, System.EventArgs e) {
_seconds += 1;

this.StopwatchText = GetElapsed();
}
private string GetElapsed() {
int hour = 0, min = 0, sec = 0;

if (_seconds > 59) {
min = (int)_seconds / 60;
sec = _seconds % 60;

if (min > 59) {
hour = (int)min / 60;
min = min % 60;
}
}
else
sec = _seconds;

string elapsed = hour < 10 ? "0" + hour.ToString() : hour.ToString();
elapsed += ":" + (min < 10 ? "0" + min.ToString() : min.ToString());
elapsed += ":" + (sec < 10 ? "0" + sec.ToString() : sec.ToString());

return elapsed;
}
}

最佳答案

这个问题可以被视为主要基于意见,但我确实相信它有助于经验较少的开发人员理解 Model-View-ViewModel 的边界。

对我来说,你认为的模型实际上是一个 ViewModel,更具体地说,父 ViewModel(故障)有一个子 ViewModel(PartMalfunction)的集合作为一个集合(ObservableCollection)公开,这意味着没有问题使用 PartMalfunction 类上的 ICommand 属性。

如果我发现一个 Model 类为显示(文本、日期等)做了很多格式的数据,那么它更有可能是一个 ViewModel,这种事情是 ViewModel 的责任。同样对我来说,Model 类不会实现 INotifyPropertyChanged 接口(interface),通知是使用事件(或 Rx 流)完成的,然后订阅者 (ViewModel) 可以选择更新 UI 的方式和时间。

关于c# - 哪一层应该包含 ICommand?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29923465/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com