代码之家  ›  专栏  ›  技术社区  ›  Julian Kolev

UWP应用程序:以MVVM方式插入/删除用户控件

  •  0
  • Julian Kolev  · 技术社区  · 8 年前

    我正在学习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:
                ...
         }
    }
    

    不确定这是最好的方法。

    2 回复  |  直到 8 年前
        1
  •  1
  •   Jerry Nixon    7 年前

    我最近也在考虑一种巫师的方法。在我看来 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>
    

    祝你好运。

        2
  •  0
  •   SledgeHammer    8 年前

    我通常使用ItemsControl。这允许您拥有通用项目模板和特定于项目的模板(如果需要),您可以通过绑定到ItemsSource随意添加/删除项目。

    控制 你加 数据

    对于您的实际示例,我猜您可以将子控件添加到ItemsControl中,它们将自动呈现,甚至不使用模板,因为ContentPresenter知道如何呈现控件。尽管如此,我仍然会使用仅数据类,因为MVVM的租户之一是将数据与UI分离。因此,您的子项将是一个模型,特定于项的模板将是绑定到项数据的UI布局。