【问题标题】:How to change WPF Window Content at Runtime [closed]如何在运行时更改 WPF 窗口内容 [关闭]
【发布时间】:2012-01-21 11:49:40
【问题描述】:

我有一个带有四个按钮的窗口,用于添加、搜索、删除和更新数据库查询。

单击其中一个按钮后,我会打开一个新窗口,其中包含这些功能的特定 WPF 控件。

如何在不打开新窗口的情况下执行此操作?一切都应该发生在一个窗口中,只有 WPF 控件应该更改和后面的代码。单击“返回”或“执行”后,我想返回主窗口。

【问题讨论】:

  • 阅读一些关于 MVVM 的文章以了解这个想法。
  • 不要再以这种方式破坏您的帖子。

标签: wpf model-view-controller mvvm controls


【解决方案1】:

密钥是ContentControl - 您将更改其内容:

<ContentControl Content="{Binding WhatToShow}"/>

在您的视图模型中,您将拥有object WhatToShow 属性。

if(some_condition) 
  WhatToShow = new SomeView(someViewModel);
else
  WhatToShow = new AnotherView(anotherViewModel);

或者你可以看看Caliburn.Micro,一个让屏幕导航更容易的MVVM框架。

【讨论】:

  • 抱歉这个新手问题,但我的知识仅限于类和数据绑定。我的视图模型是什么?
  • 视图模型对视图一无所知。因此,viewmodel 中的操作 WhatToShow = new SomeView(someViewModel) 与 MVVM 不对应。您只需要使用视图模型进行操作。
  • 不要忘记将对象 WhatToShow 的类型的 DataTemplate 添加到资源中。
  • 弗拉基米尔,你说得对,这不是纯粹的 MVVM,我只是想演示如何更改 ContentControl.Content。 Maurizio 指出,使用 DataTemplate 会更干净,只有视图模型会被推送到 WhatToShow 属性中。
【解决方案2】:

我会推荐下一种方法:

  1. 将 TabControl 放到您的视图中 - TabControl 将用于 在不同视图之间切换
  2. 为隐藏选项卡标题的 TabControl 应用样式 (how to hide tab control headers?)
  3. 为每个将要切换的视图准备视图模型,例如, 视图模型 1、视图模型 2。
  4. 准备聚合所有切换视图模型的主视图模型,例如

     public class MainViewModel : INotifyPropertyChanged
    
        {
    
             private ViewModel1 _viewModel1 = new ViewModel1();
    
             private ViewModel2 _viewModel2 = new ViewModel2();
    
             private INotifyPropertyChanged _currentViewModel;
             public INotifyPropertyChanged CurrentViewModel
             {
                 get { return _currentViewModel; }
                 set
                 {
                     _currentViewModel = value;
                     RaisePropertyChanged(() => CurrentViewModel);
                 }
              }
    
                public IEnumerable<INotifyPropertyChanged> ViewModelsToSwitch
                {
                    get
                    {
                        return new INotifyPropertyChanged[]
                                   {
                                       _viewModel1,
                                       _viewModel2
                                   };
                    }
                }
    
            // INotifyPropertyChanged implementation
    

    }

  5. 将 MainViewModel 绑定到 TabControl:

 <Window x:Class="SwitchViewDemo.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <TabControl ItemsSource="{Binding ViewModelsToSwitch}"
                        SelectedItem="{Binding CurrentViewModel}"/>
        </Grid>
    </Window>

6 .为每个视图模型声明视图:

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate DataType="{x:Type ViewModel1}">
            <TextBlock Text="View 1"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type ViewModel2}">
            <TextBlock Text="View 2"/>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <TabControl ItemsSource="{Binding ViewModelsToSwitch}"
                    SelectedItem="{Binding CurrentViewModel}"/>
    </Grid>
</Window>

7 .在 MainViewModel CurrentViewModel 中设置为 ViewModel1 或 ViewModel2 并与此视图模型视图相关联。

好处:

  • 对应于 MVVM 模式 - 所以你得到所有MVVM benefits
  • 良好的缩放。如果您想添加新的 ViewModel3,您只需将此视图模型添加到主视图模型并创建额外的 DataTemplate 来声明视图模型在指定视图上的映射。

【讨论】:

  • 您是否有一个实现 2 个视图的示例项目?我不让它工作:(
【解决方案3】:

为每个操作创建一个网格,而不是一个窗口。并在该网格中放置其特定控件。将所有网格的可见性设置为 Visibility.Collapsed。当有人按下其中一个按钮时,将相关网格的 Visibility 设置为 Visibility.Visible,将另一个设置为折叠。 话虽如此,使用 UserControls 更有条理,非常易于使用。只需在此处添加您的 XAML 并将其包含在您的主窗口中。然后像我之前说的那样隐藏和显示。

【讨论】:

  • 这也是我的第一个计划,但是在 3 或 4 个掩码之后,我认为在 XAML 中包含这么多网格并隐藏或显示它,这不是很好的组织。卡雷尔所说的方法让我印象深刻,但我不知道如何实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多