2015-12-29 192 views
-5

我想創建一個抽象ViewModel類,以及幾個ViewModel類,它們將繼承抽象ViewModel並實現它。創建抽象視圖模型wpf

到目前爲止,我使用的是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函數被調用, ViewModel已正確更改。

我錯過了什麼?

+0

你有什麼錯誤?你也可以添加你的基礎ViewModel類和RelayCommand類的代碼嗎? –

+0

顯示一些代碼! – Fruchtzwerg

+0

我一直這樣做。您是使用MVVM庫,還是隻爲自己的項目推出自己的實現?另外,發佈最少的不編譯樣本還有很長的路要讓我們來幫助你。你很可能正在實現一個接口,並且缺少該方法/屬性的抽象聲明。 –

回答

-1

好的,我發現了故障。

詮釋了MainViewModel類中,TestViewModel財產應改爲從:

public IViewModel TestViewModel 
{ 
    get { return m_testViewModel; } 
    set 
    { 
     m_testViewModel = value; 
     OnPropertyChanged("NewViewModel"); 
    } 
} 

要:

public IViewModel TestViewModel 
{ 
    get { return m_testViewModel; } 
    set 
    { 
     m_testViewModel = value; 
     OnPropertyChanged("TestViewModel"); 
    } 
} 
1

自定義MVVM從創建實現INotifyPropertyChanged接口的抽象ViewModelBase類開始。

但是,根據您的RelayCommand評論,我假設您使用MVVM Light框架?然後,而不是實現INotifyPropertyChanged您的抽象ViewModel應繼承從MVVM燈ViewModelBase類。

RelayCommands將是您的ViewModelBase的屬性,而不是您繼承的基類。

+0

更新了我的問題。 – Idanis