Как я могу привязать к подчиненной модели представления, используя наследование ViewModel? - PullRequest
0 голосов
/ 17 апреля 2020

В моем приложении у меня есть следующий MasterViewModel1-класс.

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-классом.

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.

Внутри MasterView необходимо связать с обоими, MasterViewModel, поэтому у меня есть «Базовый дизайн» ». И мне нужно привязать к «Sub» ViewModel, в этом примере TestViewModel.

Представление MasterViewModel1

На изображении вы можете увидеть MasterView. Обозначенная красным область - это место, где нужно разместить TestViewModel (TestView). Я не могу использовать статический ресурс !!! Это должно быть Dynami c, поэтому, если я создаю другую ViewModel, которая также наследуется от MasterViewModel1. Обозначенная красным область должна меняться в зависимости от экземпляра ViewModel.

Надеюсь, все понятно. Если вам нужна дополнительная информация, пожалуйста, спросите.

1 Ответ

0 голосов
/ 17 апреля 2020

Как правило, все публичные c свойства суперкласса видимы и доступны через каждый подкласс. Вы можете привязать к каждому объекту publi c.

Если вы хотите изменить макет или внешний вид представления на основе фактической реализации или типа, вам следует использовать DataTemplate, который описывает структуру представления и привязку к данным модели.
Простой ContentControl будет служить динамическим c узлом просмотра.

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>
...