我正在学习UWP,试图将旧的Win32移植到新平台。我正在使用Template10,到目前为止一切运行正常,除了我对如何实现下面的问题感到困惑。
问题:在页面中,我必须根据视图模型属性不断删除和插入用户控件。用户控件相当复杂,它们的外观和行为都不同。想象一个带有后退和下一个按钮的向导。每次点击我都要删除旧内容并插入一个新内容,使用完全不同的视图模型。
问题:以MVVM方式实现此方法的推荐方法是什么?
目前,我唯一的想法是从页面的视图模型中发送一条消息,并在页面代码中订阅消息,在那里我可以创建所需的组件并在页面中动态插入(删除旧的后)
在MyPageViewModel中:
public IComponentViewModel CurrentComponent {get; set;}
...
public DelegateCommand NextItemCommand = new DelegateCommand(() =>
{
var evt = App.EventAggregator.GetEvent<ItemChangedMessage>();
evt.Publish(CurrentComponent);
});
在MyPage.xaml.cs代码背后
public MyPage()
{
InitializeComponent();
var evt = App.EventAggregator.GetEvent<ItemChangedMessage>();
evt.Subscribe(OnItemChanged);
}
private void OnItemChanged(IComponentViewModel viewModel)
{
switch (viewModel.Type)
{
case 1:
// create the new user control and insert it in the container
var component = new TypeOneComponent();
component.DataContext = (TypeOneCompoentViewModel)viewModel;
// ...
case 2:
...
}
}
不确定这是最好的方法。
答案 0 :(得分:1)
我最近一直在考虑向导方法。在我看来,具有重新模板左/右按钮的FlipView
是最简单的方法。我的WizardViewModel将有几个子视图模型;像Page1ViewModel,Page2ViewModel等等。我强烈认为每个页面视图模型都有一个专用的UserControl
所以UI可以是唯一的但不是动态的 - 我认为设计动态UI是有意义的,同时拥抱自适应UI - 这是一个完全不同的概念。
伪代码可能如下所示:
public interface IWizardPage { }
public class Page1ViewModel : ViewModelBase, IWizardPage { }
public class Page2ViewModel : ViewModelBase, IWizardPage { }
public class Page3ViewModel : ViewModelBase, IWizardPage { }
public class MainPageViewModel : ViewModelBase
{
public IWizardPage CurrentPage { get; set; }
public IWizardPage Page1ViewModel { get; set; }
public IWizardPage Page2ViewModel { get; set; }
public IWizardPage Page3ViewModel { get; set; }
}
而且:
<FlipView Template="{StaticResource WizardFlipView}"
SelectedItem="{Binding CurrentPage, Mode=TwoWay}">
<Page1UserControl DataContext="{Binding Page1ViewModel}" />
<Page2UserControl DataContext="{Binding Page2ViewModel}" />
<Page3UserControl DataContext="{Binding Page3ViewModel}" />
</FlipView>
这只是一个建议。但是要回答你的问题,这将非常适合MVVM模式。我也认为这样可以让你变得非常灵活,而不会变得如此动态,以至于维护费用非常耗时。有很多方法可以做巫师。我认为这将是一个很好的解决方案,对MVVM模式很好,对模板10很好。
祝你好运。
答案 1 :(得分:0)
我通常使用ItemsControl。如果需要,这允许您拥有通用项目模板和项目特定模板,您可以通过绑定到ItemsSource随意添加/删除项目。
在您的向导示例中,您可以使主向导容器成为一个ItemsControl,它一次只显示一个项目,而页面将是&#34; item&#34;。与MVVM的区别在于,您不添加子控件,添加数据,然后指定一个模板来呈现它。所以你的物品将是简单的数据包poco对象。
对于您的实际示例,我猜您可以将子控件添加到ItemsControl,并且它们将自动呈现,甚至不使用模板,因为ContentPresenter知道如何呈现控件。我仍然会使用仅数据类,因为MVVM的一个租户是将数据与UI分开。因此,您的子项目将是模型,您的项目特定模板将是绑定到项目数据的UI布局。