1

我请求您帮助解决一些说得简单而且很可能只是完成但目前不适合我的事情。我正在开发的是一个使用 FluidUI 控件集看起来像 Of​​fice 2013 的应用程序。我想从 Word/Access 中实现视图切换器,其中功能区上有“视图”选项卡,并且有用于切换视图的按钮。我认为将整个 View 对象存储在我的 ViewModel 的属性 CurrentView 中是错误的方式,我试图使这个应用程序尽可能地成为纯 MVVM。这个应用程序更像是“如何使用 MVVM 编写应用程序”,因为我还在学习 WPF。行。所以我有我的窗口(正确的是 MainWindowModern),它有 Fluid Ribbon。有 3 个按钮可以切换视图(我称它们为编辑器)。他们所做的是改变 MainWindowModern 的 ViewModel' s CurrentView 属性并为其设置新的枚举值。这部分设置新的枚举值已经完成并且可以工作。现在。窗口的主体只是 ContentControl。现在我想根据 DataContext.CurrentView 属性值更改此 ContentControl 的 Content 属性。就像我之前说的。我不想在视图的 c#(我正在用 C# 编写这个应用程序)文件中做任何代码隐藏。唯一不起作用的只是更改 ContentControl Content 属性。我正在尝试使用 DataTemplates 和 DataTemplate.Triggers 来做到这一点 不想在视图的 c#(我正在用 C# 编写这个应用程序)文件中执行任何代码隐藏。唯一不起作用的只是更改 ContentControl Content 属性。我正在尝试使用 DataTemplates 和 DataTemplate.Triggers 来做到这一点 不想在视图的 c#(我正在用 C# 编写这个应用程序)文件中执行任何代码隐藏。唯一不起作用的只是更改 ContentControl Content 属性。我正在尝试使用 DataTemplates 和 DataTemplate.Triggers 来做到这一点

现在这是我到目前为止所得到的(没有不相关的代码)。

窗口的 XAML

<Fluent:MetroWindow
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Fluent="clr-namespace:Fluent;assembly=Fluent"
    xmlns:localVM="clr-namespace:MVVMTest.ViewModels"
    xmlns:local="clr-namespace:MVVMTest"
    x:Class="MVVMTest.Views.MainWindowModern"
    x:Name="ThisWindow"
    Title="Dialogue Editor (Modern UI Version)"
    Width="1280" Height="480"
    RibbonThemeColor="Red" WindowState="Maximized"
    Icon="..\Assets\App\AppIcon_32x32.png">

    <Window.Resources>
        <DataTemplate x:Key="CharactersEditorTemplate">
            <TextBlock Text="Characters Editor Template Body" />
        </DataTemplate>
        <DataTemplate x:Key="ChaptersEditorTemplate">
            <TextBlock Text="Chapters Editor Template Body" />
        </DataTemplate>
        <DataTemplate x:Key="ConversationsEditorTemplate">
            <TextBlock Text="Conversations Editor Template Body" />
        </DataTemplate>
        <DataTemplate x:Key="aaa" DataType="{x:Type ContentControl}" >
            <TextBlock Text="{Binding ElementName=ThisWindow, Path=DataContext.CurrentView}" />
            <DataTemplate.Triggers>
                <!--<DataTrigger Binding="{Binding CurrentView}">
                    <DataTrigger.Value>
                        <localVM:EditorView>CharactersEditor</localVM:EditorView>
                    </DataTrigger.Value>
                    <Setter Property="Content" Value="{StaticResource CharactersEditorTemplate}" />
                </DataTrigger>
                <DataTrigger Binding="{Binding CurrentView}">
                    <DataTrigger.Value>
                        <localVM:EditorView>ChaptersEditor</localVM:EditorView>
                    </DataTrigger.Value>
                    <Setter Property="Content" Value="{StaticResource ChaptersEditorTemplate}" />
                </DataTrigger>
                <DataTrigger Binding="{Binding CurrentView}">
                    <DataTrigger.Value>
                        <localVM:EditorView>ConversationsEditor</localVM:EditorView>
                    </DataTrigger.Value>
                    <Setter Property="Content" Value="{StaticResource ConversationsEditorTemplate}" />
                </DataTrigger>-->

                <DataTrigger Binding="{Binding ElementName=ThisWindow, Path=DataContext.CurrentView}">
                    <DataTrigger.Value>
                        <localVM:EditorView>ChaptersEditor</localVM:EditorView>
                    </DataTrigger.Value>
                    <DataTrigger.Setters>
                        <Setter Property="Content" Value="{StaticResource ChaptersEditorTemplate}" />
                    </DataTrigger.Setters>
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </Window.Resources>

    <Window.DataContext>
        <localVM:MainWindowVM />
    </Window.DataContext>

    <DockPanel x:Name="LayoutRoot" LastChildFill="True">
        <Fluent:Ribbon DockPanel.Dock="Top">

            <Fluent:RibbonTabItem Header="VIEW" Fluent:KeyTip.Keys="V" ReduceOrder="ViewsRibbonGroupBox, ViewsRibbonGroupBox, ViewsRibbonGroupBox">

                <Fluent:RibbonGroupBox Name="ViewsRibbonGroupBox" Header="Views">

                    <Fluent:Button Name="CharactersViewButton" 
                                   Header="Characters" 
                                   LargeIcon="..\Assets\Ribbon\View\CharacterEditorIcon_32x32.png"
                                   Icon="..\Assets\Ribbon\View\CharacterEditorIcon_32x32.png"
                                   Command="{Binding SwitchToCharactersEditorCommand}" >
                        <Fluent:Button.ToolTip>
                            <Fluent:ScreenTip
                                Image="..\Assets\Ribbon\View\CharacterEditorIcon_32x32.png"
                                Title="Characters Editor"
                                Text="Changes current view to Characters Editor view.&#x0a;&#x0a;In this view user can:&#x0a;&#x2022; List existing characters&#x0a;&#x2022; Create new characters&#x0a;&#x2022; Edit existing characters&#x0a;&#x2022; Delete existing characters&#x0a;&#x0a;It is also possible to manage character's emotions in this view." />
                        </Fluent:Button.ToolTip>
                    </Fluent:Button>

                    <Fluent:Button Name="ChaptersViewButton" 
                                   Header="Chapters" 
                                   LargeIcon="..\Assets\Ribbon\View\ChapterEditorIcon_32x32.png"
                                   Icon="..\Assets\Ribbon\View\ChapterEditorIcon_32x32.png"
                                   Command="{Binding SwitchToChaptersEditorCommand}" >
                        <Fluent:Button.ToolTip>
                            <Fluent:ScreenTip
                                Image="..\Assets\Ribbon\View\ChapterEditorIcon_32x32.png"
                                Title="Chapters Editor"
                                Text="Changes current view to Chapters Editor view.&#x0a;&#x0a;In this view user can:&#x0a;&#x2022; List existing chapters&#x0a;&#x2022; Create new chapters&#x0a;&#x2022; Edit existing chapters&#x0a;&#x2022; Delete existing chapters&#x0a;&#x0a;It is also possible to manage chapters's missions in this view." />
                        </Fluent:Button.ToolTip>
                    </Fluent:Button>

                    <Fluent:Button Name="ConversationsViewButton" 
                                   Header="Conversations" 
                                   LargeIcon="..\Assets\Ribbon\View\ConversationEditorIcon_32x32.png"
                                   Icon="..\Assets\Ribbon\View\ConversationEditorIcon_32x32.png"
                                   Command="{Binding SwitchToConversationsEditorCommand}" >
                        <Fluent:Button.ToolTip>
                            <Fluent:ScreenTip
                                Image="..\Assets\Ribbon\View\ConversationEditorIcon_32x32.png"
                                Title="Conversations Editor"
                                Text="Changes current view to Conversations Editor view.&#x0a;&#x0a;In this view user can:&#x0a;&#x2022; List existing conversations&#x0a;&#x2022; Create new conversations&#x0a;&#x2022; Edit existing conversations&#x0a;&#x2022; Delete existing conversations&#x0a;&#x0a;It is also possible to manage conversations's statements and statement's stages in this view."
                                DisableReason="Please define at least one chapter with at least one mission in it to enable Conversations Editor.&#x0a;Also it would be helpful to define at least one character with at least one emotion.&#x0a;It is optional action but highly recommended." />
                        </Fluent:Button.ToolTip>
                    </Fluent:Button>

                </Fluent:RibbonGroupBox>
            </Fluent:RibbonTabItem>

        </Fluent:Ribbon>

        <ContentControl Name="MainContent" ContentTemplate="{StaticResource aaa}" />

    </DockPanel>
</Fluent:MetroWindow>

Window 的 ViewModel 和枚举

using MVVMTest.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MVVMTest.ViewModels {
    public enum EditorView {
        CharactersEditor,
        ChaptersEditor,
        ConversationsEditor
    }

    public class MainWindowVM : ViewModelBase {

        public MainWindowVM() {
            this.init();
        }

        protected void init() {
            this.Characters = new ObservableCollection<CharacterVM>();

            this.initCommands();
            this.initSampleData();
        }

        protected void initSampleData() {
            Character ch1 = new Character() { Name = "Character 1" };
            Emotion e1 = new Emotion() { Name = "Emotion 1" };
            ch1.Emotions.Add(e1);
            CharacterVM ch1vm = new CharacterVM(ch1);
            this.Characters.Add(ch1vm);

            this.CurrentView = EditorView.ConversationsEditor;
        }

        protected void initCommands() {
            this.SwitchToCharactersEditorCommand = new RelayCommand(param => this.SwitchToCharactersEditor(), param => this.CanSwitchToCharactersEditor());
            this.SwitchToChaptersEditorCommand = new RelayCommand(param => this.SwitchToChaptersEditor(), param => this.CanSwitchToChaptersEditor());
            this.SwitchToConversationsEditorCommand = new RelayCommand(param => this.SwitchToConversationsEditor(), param => this.CanSwitchToConversationsEditor());
        }

        public ObservableCollection<CharacterVM> Characters { get; set; }

        protected EditorView _currentView;
        public EditorView CurrentView {
            get { return this._currentView; }
            set {
                if (this._currentView == value) {
                    return;
                }
                this._currentView = value;
                this.OnPropertyChanged("CurrentView");
            }
        }

        #region Commands

        #region View Tab

        #region Switch To Characters Editor
        public RelayCommand SwitchToCharactersEditorCommand { get; private set; }
        protected void SwitchToCharactersEditor() {
            this.CurrentView = EditorView.CharactersEditor;
        }
        protected bool CanSwitchToCharactersEditor() {
            if (this.CurrentView != EditorView.CharactersEditor) {
                return true;
            }
            return false;
        }
        #endregion Switch To Characters Editor

        #region Switch To Chapters Editor
        public RelayCommand SwitchToChaptersEditorCommand { get; private set; }
        protected void SwitchToChaptersEditor() {
            this.CurrentView = EditorView.ChaptersEditor;
        }
        protected bool CanSwitchToChaptersEditor() {
            if (this.CurrentView != EditorView.ChaptersEditor) {
                return true;
            }
            return false;
        }
        #endregion Switch To Chapters Editor

        #region Switch To Conversations Editor
        public RelayCommand SwitchToConversationsEditorCommand { get; private set; }
        protected void SwitchToConversationsEditor() {
            this.CurrentView = EditorView.ConversationsEditor;
        }
        protected bool CanSwitchToConversationsEditor() {
            if (this.CurrentView != EditorView.ConversationsEditor) {
                return true;
            }
            return false;
        }
        #endregion Switch To Conversations Editor

        #endregion View Tab

        #endregion Commands
    }
}

当这一切都完成后,下一步就是像在 ModernUI 应用程序(或 android 智能手机)上一样为视图开关添加动画,这样旧的内容就会越过窗口的边界,而新的内容来自另一边。如果不可能,那么我将只使用工作切换器。

4

2 回答 2

0

好消息是这实际上很容易做到,包括动画切换。您需要的是一个 ItemsControl 来托管您的子视图。ItemsControl 允许您使用 DataTemplateSelector。因此,根据您的枚举值,您可以生成一些输出,选择器可以使用这些输出来确定要使用的数据模板。尝试对选择器进行一些研究。如果您仍然感到困惑,请随时与我联系。祝你好运。

于 2013-01-04T00:14:56.960 回答
0

对于动画,我建议使用一个容器控件来托管您的子视图。查看此链接以获得一个非常可靠的实现来帮助您入门。

于 2013-01-04T17:40:17.360 回答