我正在尝试创建一个抽象的ViewModel类,以及几个将继承抽象ViewModel并实现它的ViewModel类。
到目前为止,我正在使用RelayCommand
并且它无法编译。
可以这样做吗?
我正在添加我的代码:
RelayCommand类:
public class RelayCommand : ICommand
{
private readonly Action<object> m_executeAction;
private readonly Predicate<object> m_canExecute;
public RelayCommand(Action<object> executeAction) : this(executeAction, null) { }
public RelayCommand(Action<object> executeAction, Predicate<object> canExecute)
{
if (executeAction == null)
throw new ArgumentNullException("executeAction");
m_executeAction = executeAction;
m_canExecute = canExecute;
}
public bool CanExecute(object canExecuteParameter)
{
return (m_canExecute == null || m_canExecute(canExecuteParameter));
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object canExecuteParameter)
{
m_executeAction(canExecuteParameter);
}
}
ViewModelsBase类:
public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged == null) return;
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnDispose() {}
public void Dispose()
{
OnDispose();
}
}
MainViewModel类:
public class MainWindowViewModel : ViewModelBase
{
private IViewModel m_testViewModel;
private bool m_isFirstPlugin = true;
public MainWindowViewModel()
{
TestViewModel = new FirstViewModel();
}
public IViewModel TestViewModel
{
get { return m_testViewModel; }
set
{
m_testViewModel = value;
OnPropertyChanged("NewViewModel");
}
}
private ICommand m_changeCommand;
public ICommand ChangeCommand
{
get { return m_changeCommand ?? (m_changeCommand = new RelayCommand(Change)); }
set { m_changeCommand = value; }
}
private void Change(object parameter)
{
TestViewModel.Dispose();
TestViewModel = null;
if (m_isFirstPlugin)
TestViewModel = new SecondViewModel();
else
TestViewModel = new FirstViewModel();
m_isFirstPlugin = !m_isFirstPlugin;
}
}
IViewModel类:
public class IViewModel : ViewModelBase
{
private ICommand m_testCommand;
public ICommand TestCommand
{
get { return m_testCommand ?? (m_testCommand = new RelayCommand(Test)); }
set { m_testCommand = value; }
}
protected virtual void Test(object parameter) { }
}
FirstViewModel类:
public class FirstViewModel : IViewModel
{
protected override void Test(object parameter)
{
MessageBox.Show("On First Plugin.");
}
}
SecondViewModel类:
public class SecondViewModel : IViewModel
{
protected override void Test(object parameter)
{
MessageBox.Show("On Second Plugin.");
}
}
的Xaml:
<Window x:Class="MvvmInheritence.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Testing" Height="100" Width="180"
xmlns:Local="clr-namespace:MvvmInheritence" WindowStartupLocation="CenterScreen" Background="Transparent">
<Window.DataContext>
<Local:MainWindowViewModel />
</Window.DataContext>
<Grid x:Name="MainGrid">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button x:Name="TestButton" Content="Test!" Foreground="DarkRed" Background="LightBlue" Height="25" Width="100" Command="{Binding TestCommand, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DataContext="{Binding TestViewModel, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Row="0"/>
<Button x:Name="ChangeButton" Content="Change Plugin" Foreground="DarkRed" Background="LightBlue" Height="25" Width="100" Command="{Binding ChangeCommand, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1"/>
</Grid>
</Window>
此代码确实编译(我进行了更改以使其工作)但由于某种原因,即使调用了Change
函数,我也总是得到“On First Plugin”,ViewModel
已正确更改。
我错过了什么?
答案 0 :(得分:1)
自定义MVVM首先创建一个实现INotifyPropertyChanged
接口的抽象ViewModelBase类。
但是,基于您的RelayCommand
评论,我假设您正在使用MVVM Light框架?然后,而不是实现INotifyPropertyChanged
,您的抽象ViewModel应该继承自MVVM Lights ViewModelBase
类。
RelayCommands将是您的ViewModelBase的属性,而不是您继承的基类。
答案 1 :(得分:-1)
好的,我发现了故障。
在enum Name<T> where T:Borrow<str> {
Single(T),
Double(T, T),
}
// these both work now
let _a1 = Name::Single("hello");
let _a2 = Name::Double(String::from("hello"), String::from("world"));
类中,MainViewModel
属性应更改为:
TestViewModel
要:
public IViewModel TestViewModel
{
get { return m_testViewModel; }
set
{
m_testViewModel = value;
OnPropertyChanged("NewViewModel");
}
}