Динамическое переключение между представлениями в WPF с использованием MVVM - PullRequest
0 голосов
/ 02 июля 2019

Я относительно новичок в WPF и шаблоне MVVM.Я пытаюсь сделать так, чтобы вложенный пользовательский элемент управления переключал свое представление на основе DependencyProperty, определенного в MasterView.

То, что у меня есть, - это UserControl, давайте назовем его LineItemsHolderView, который содержит другие пользовательские элементы управления, которые заполнены.использование ItemsContol.

LineItemsHolderView предназначается для заполнения другим UserControl, называемым MainLineItemView.

Цель MainLineItemView - переключиться на определенный тип LineItemView на основе DependencyProperty, определенного в MainLineItemView.

Два типа LineItemView - это LineItemSummaryView и LineItemDetailView, каждый из которых имеет свой собственный ViewModel.связанный с ними.

В каждом представлении я устанавливаю DataContext на соответствующий ViewModel в конструкторе и создаю привязки из представлений DependencyProperties к свойствам ViewModels INotifyPropertyChanged.(Я приведу примеры кода ниже)

Работая в предположении, что View / ViewModels были связаны и созданы правильно, я пытаюсь использовать ContentControl в MainLineItemView для отображения правильного представления на основе DependencyPropery,целое число, называемое SwitchView, созданное в MainLineItemView.

Однако при установке этого значения из ItemControl DataTemplate ItemsIontmsHolderView оно не обновляет тип MainLineItemView, отображаемый в LineItemsHolderView.

LineItemsHolderView.xaml

 <Grid>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="5*" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>

         <ScrollViewer Grid.Row="1">
                <ItemsControl ItemsSource="{Binding LineItems}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <view:MainLineItemView SwitchView="1" Height="100" Padding="0,5,0,5" LineItem="{Binding RelativeSource={RelativeSource Self}}"/>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
        </ScrollViewer>
  </Grid>
</Grid>

LineItemsHolderView.xaml.cs

public partial class LineItemsHolderView : UserControl
    {
        public LineItemsHolderView()
        {
            InitializeComponent();
            DataContext = new LineItemsHolderViewModel();
        }
    }

LineItemsHolderViewModel.cs

internal class LineItemsHolderViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<Models.LineItem> LineItems { get; set; }
        public LineItemsHolderViewModel ()
        {
            LineItems = new ObservableCollection<Models.LineItem>();
            for (int i = 0; i < 4; i++)
                LineItems.Add(new Models.LineItem(i));
        }


        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }

MainLineItemView.xaml

<UserControl.Resources>
        <DataTemplate x:Key="SummaryView"  DataType="{x:Type vm:LineItemSummaryViewModel}">
            <local:LineItemSummaryView LineItem="{Binding LineItem}"/>
        </DataTemplate>
        <DataTemplate x:Key="DetailView" DataType="{x:Type vm:LineItemSummaryViewModel}">
            <local:LineItemDetailView LineItem="{Binding LineItem}"/>
        </DataTemplate>
    </UserControl.Resources>
    <Grid>
        <ContentControl Content="{Binding SelectedViewModel}">
            <ContentControl.Style>
                <Style TargetType="{x:Type ContentControl}">
                    <Setter Property="ContentTemplate" Value="{StaticResource SummaryView}" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding SwitchView, diag:PresentationTraceSources.TraceLevel=High}" Value="1">
                            <Setter Property="ContentTemplate" Value="{StaticResource DetailView}" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
    </Grid>

MainLineItemView.xaml.cs

public partial class MainLineItemView : UserControl
    {
        public MainLineItemView()
        {
            InitializeComponent();

            this.DataContext = new MainLineItemViewModel();

            var bindingSwitchView = new Binding("SwitchView") { Mode = BindingMode.TwoWay };
            this.SetBinding(SwitchProperty, bindingSwitchView);

            var lineItemData = new Binding("LineItem") { Mode = BindingMode.TwoWay };
            this.SetBinding(LineItemProperty, lineItemData);
        }

        #region SwitchView DP
        public int SwitchView
        {
            get { return (int)GetValue(SwitchProperty); }
            set { SetValue(SwitchProperty, value); }
        }
        public static readonly DependencyProperty SwitchProperty = DependencyProperty.Register("SwitchView", typeof(int), typeof(MainLineItemView));
        #endregion

        #region LineItem DP
        public LineItem LineItem
        {
            get { return (LineItem)GetValue(LineItemProperty); }
            set { SetValue(LineItemProperty, value); }
        }
        public static readonly DependencyProperty LineItemProperty =
            DependencyProperty.Register("LineItem", typeof(LineItem),
              typeof(MainLineItemView));
        #endregion
    }

MainLineItemViewModel.cs

internal class MainLineItemViewModel : INotifyPropertyChanged
    {
        private int _currentView;
        public int CurrentView
        {
            get { return _currentView; }
            set
            {
                _currentView = value;
                OnPropertyChanged("CurrentView");
            }
        }
        private LineItem _lineItem;
        public LineItem LineItem
        {
            get { return _lineItem; }
            set
            {
                _lineItem= value;
                OnPropertyChanged("LineItem");
            }
        }

        public MainLineItemViewModel()
        {
        }

        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }

Я могу предоставить LineItemSummaryView / LineItemSummaryViewModel и LineItemDetailView / LineItemDetailViewModel, если необходимо.

Я ожидаю при установке SwitchView = "1" в LineItems., LineItemDetailView ПоказатьЯ буду отображаться в пользовательском интерфейсе.

Я рад любым улучшениям, которые я могу внести в этот процесс, поскольку я только начинающий в WPF.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...