我对WPF和MVVM模式还比较陌生。我正在尝试做的是让一个嵌套的用户控件根据MasterView中定义的DependencyProperty切换其视图。
我拥有的是一个UserControl,我们称其为LineItemsHolderView,其中包含使用ItemsContol填充的其他用户控件。
LineItemsHolderView用于填充另一个名为MainLineItemView的UserControl。
MainLineItemView的目的是根据MainLineItemView中定义的DependencyProperty将自身切换到LineItemView的特定类型。
LineItemView的两种类型是LineItemSummaryView和LineItemDetailView,它们各自具有自己的ViewModel。
在每个视图中,我将DataContext设置为构造函数中的相应ViewModel,并创建从视图DependencyProperties到ViewModels INotifyPropertyChanged属性的绑定。 (我将在下面提供代码示例)
在假设View / ViewModels已正确绑定和创建的前提下,我试图在MainLineItemView中使用ContentControl来显示基于DependencyPropery(在MainLineItemView中创建的名为SwitchView的整数)的正确视图。
但是,从LineItemsHolderView的ItemsControl DataTemplate设置此值时,它不会更新LineItemsHolderView中显示的MainLineItemView类型。
<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>
public partial class LineItemsHolderView : UserControl
{
public LineItemsHolderView()
{
InitializeComponent();
DataContext = new LineItemsHolderViewModel();
}
}
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
}
<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>
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
}
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。
我希望在LineItemsHolderView.xaml中设置SwitchView =“ 1”时,应该在UI上显示LineItemDetailView。
由于我只是WPF的初学者,因此我可以对此进行任何改进,我们对此表示欢迎。