我如何使用ViewModel继承绑定到子ViewModel?

问题描述 投票:0回答:1

在我的应用程序中,我具有以下MasterViewModel1-class。

public class MasterViewModel1 : ViewModelBase
{
    private ObservableCollection<ObservableObject> _MainGrid;

    public ObservableCollection<ObservableObject> MainGrid
    {
        get => _MainGrid;
        set
        {
            _MainGrid = value;
            RaisePropertyChanged();
        }
    }

    public ObservableCollection<FilterItem> FilterItems
    {
        get;
        set;
    }

    public MasterViewModel1()
    {
        CreateDefaultMenu();
    }

    public void CreateDefaultMenu()
    {
        FilterItems = new ObservableCollection<FilterItem>
        {
            new FilterItem(OnFilterClicked)
            {
                Content = "Filter"
            },
            new FilterItem(OnFilterCancelClicked)
            {
                Content = "Filter aufheben"
            }
        };
    }

    public virtual void OnFilterClicked() { }
    public virtual void OnFilterCancelClicked() { }

MasterViewModel1-类由TestViewModel-class继承。

public class TestViewModel : MasterViewModel1
{
    private Kunde _NeuerKunde;
    public Kunde NeuerKunde
    {
        get => _NeuerKunde;
        set => _NeuerKunde = value;
    }

    private string _Kundenmatchcode;
    public string Kundenmatchcode
    {
        get => _Kundenmatchcode;
        set
        {
            _Kundenmatchcode = value;
            RaisePropertyChanged();
        }
    }

    public TestViewModel()
    {
        NeuerKunde = new Kunde();
    }
}

出于可重用的原因,我使用MasterViewModel1-类及其视图,因为将来会有更多的视图继承MasterViewModel。

需要将MasterViewModel绑定到MasterView里面,所以我有“ Base-Design”。而且我需要绑定到“ Sub” ViewModel,在此示例中为TestViewModel。

View of the MasterViewModel1

在图像中,您可以看到MasterView。红色标记的区域是应放置TestViewModel(TestView)的地方。我不能使用staticresource !!!它必须是动态的,所以如果我实例化另一个ViewModel,它也继承自MasterViewModel1。标记为红色的区域应根据实例化的ViewModel进行更改。

我希望足够清楚。如果您需要更多信息,请询问。

c# wpf mvvm binding viewmodel
1个回答
0
投票

通常,超类的所有公共属性都可以通过每个子类看到和访问。您可以绑定到每个公共财产。

如果要根据实际实现或类型更改视图的布局或外观,则应使用DataTemplate,该视图描述视图的结构和绑定到模型数据的方式。一个简单的ContentControl将用作动态视图主机。

ViewModelBase.cs

public class ViewModelBase : INotifyPropertyChanged
{    
  public event PropertyChangedEventHandler PropertyChanged;
  protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
  {
    this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }
}

MainViewModel.cs

public class MainViewModel : ViewModelBase 
{   
  private ViewModelBase currentView;   
  public ViewModelBase CurrentView
  {
    get => this.currentView;
    set 
    { 
      this.currentView= value; 
      OnPropertyChanged();
    }
  }

  public ICommand ToggleViewCommand => new RelayCommand(param => this.CurrentView = this.Views.FirstOrDefault(view => view != this.CurrentView));

  private List<ViewModelBase> Views { get; }

  public MainViewModel()
  {
    this.Views = new ObservableCollection<ViewModelBase>()
    {
      new TestViewModel() { Value = "TestViewModel View" },
      new AnotherTestViewModel() { Name = "AnotherTestViewModel View" }
    }

    this.CurrentView = this.Views.First();
  }
}

TestViewModel.cs

public class TestViewModel : ViewModelBase
{
  private string value;   
  public string Value
  {
    get => this.value;
    set 
    { 
      this.value = value; 
      OnPropertyChanged();
    }
  }
}

AnotherTestViewModel.cs

public class TestViewModel : ViewModelBase
{
  private string name;   
  public string Name
  {
    get => this.name;
    set 
    { 
      this.name = value; 
      OnPropertyChanged();
    }
  }
}

TestView.xaml

<Window>
  <Window.DataContext>
    <TestViewModel />
  </Window.DataContext>

  <TextBlock Text="{Binding Value}" />
</Window>

MainWindow.xaml

<Window>
  <Window.DataContext>
    <MainViewModel />
  </Window.DataContext>

  <Window.Resources>

    <!-- Define the views as an implicit (keyless) DataTemplate -->
    <DataTemplate DataType="{x:Type TestViewModel}">

      <!-- Show a view as a UserControl -->
      <TestView />
    </DataTemplate>

    <DataTemplate DataType="{x:Type AnotherTestViewModel}">

      <!-- Or add a elements -->
      <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding Name}" />
        <Rectangle Height="80" Width="80" Fill="Red" />
      </StackPanel>
    </DataTemplate>
  </Window.Resources>

  <StackPanel>
    <Button Command="{Binding ToggleViewCommand}" Content="Toggle View" />

    <!-- 
      Host of the different views based on the actual model type (dynamic view).
      The implicit DataTemplates will apply automatically
      and show the view that maps to the current CurrentView view model type
    -->
    <ContentControl Content="{Binding CurrentView}" />
  </StackPanel>
</Window>
© www.soinside.com 2019 - 2024. All rights reserved.