我是WPF和MVVM的新手,但我正在尝试做一个简单的项目。我的应用程序基本上由一个窗口组成,该窗口有两个TabItems和一个通用的进度条;在每个TabItem中都有一些对FTP通信或类似内容的控制。就其含义而言,没有必要用多个视图使其变得复杂,但我想使其尽可能干净。我的想法是创建三个ViewModel,一个用于每个TabItem,另一个用于";公共控制";,比如进度条(用于FTP传输进度(,并且能够从TabItem1VM和TabItem2VM访问CommonVM。我已经读到一个好的方法可以是使用singleton CommonVM,但是如果我想为Progress bar属性和其他一些属性实现INotifyPropertyChanged,我该如何处理singleton?
现在我画了这样的东西,但我觉得很乱:
internal class Notifier : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
internal class ViewModelCommon : Notifier
{
public static ViewModelCommon Instance = new ViewModelCommon();
public bool OperationInProgress
{
get { return GetInstance().OperationInProgress; }
set {
GetInstance().OperationInProgress = value;
OnPropertyChanged("OperationInProgress");
}
}
private ViewModelCommon() { }
internal static ViewModelCommon GetInstance()
{
if(Instance == null )
{
Instance = new ViewModelCommon();
}
return Instance;
}
}
internal class ViewModelBase : Notifier
{
public ViewModelCommon VMCommmon
{
get { return ViewModelCommon.GetInstance(); }
}
}
internal class ViewModel1 : ViewModelBase
{
}
internal class ViewModel2 : ViewModelBase
{
}
您的实现有点错误
在WPF中,除非在作业条件中明确指定了封装,否则最好使用公共类型
像这样修复(.Net 5+(。
第一个变体是Singleton实现
public class ViewModelCommon : BaseInpc
{
private static ViewModelCommon _instance
public static ViewModelCommon Instance => _instance
??= new ViewModelCommon();
private bool _operationInProgress
public bool OperationInProgress
{
get => _operationInProgress;
set => Set(ref _operationInProgress, value);
}
private ViewModelCommon() { }
}
BaseInpc是我的简单INotifyPropertyChanged实现:BaseInpc
绑定到此类:
<CheckBox IsChecked="{Binding OperationInProgress, Source={x:Static vms:ViewModelCommon.Instance}}" .../>
vms:
是ViewModelCommon类的命名空间前缀。
第二种变体是在应用程序资源中创建一个实例
public class ViewModelCommon : BaseInpc
{
private bool _operationInProgress
public bool OperationInProgress
{
get => _operationInProgress;
set => Set(ref _operationInProgress, value);
}
}
<Application.Resources>
<vms:ViewModelCommon x:Key="commonVM"
OperationInProgress="True"/>
</Application.Resources>
如果在创建实例时需要更改默认值,则会将OperationInProgress属性的值设置为示例。
绑定到此实例:
<CheckBox IsChecked="{Binding OperationInProgress, Source={StaticResource commonVM}}" .../>