• 基于WPF系统框架设计(4)-Ribbon整合Avalondock 2.0实现多文档界面设计(一)


    前些时间研究了WPF的一些框架,感觉基于Prism框架的MVVM模式对系统的UI与逻辑分离很好,所以就按照之前Winform的框架设计,用WPF做了一套,感觉比Winform要强很多。

    MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大优点

    1. 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。

    2. 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。

    3. 独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,使用Expression Blend可以很容易设计界面并生成xaml代码。

    4. 可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

    MVVM功能图:

    1

    现在我做了个实例,整合模仿Office 2010的Ribbon效果:

    (1)Blue:

    systemUI

    (2)Silver

    silver2

    (3)Black

    black

    black2

    我把框架的View设计和框架设计简单介绍一下。

    View的XAML源码:

    <!--<Window x:Class="TLAgent.Ribbon.App.Demo.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>
            
        </Grid>
    </Window>-->
    <Fluent:RibbonWindow x:Class="TLAgent.Ribbon.App.Demo.MainWindow"
        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:ad="http://schemas.xceed.com/wpf/xaml/avalondock"
        xmlns:vm="clr-namespace:TLAgent.Ribbon.App.Demo"
        Title="TLAgent.Ribbon.Application" Width="500" Height="250" Background="#FFEBEDF0" x:Name="window" WindowState="Maximized" WindowStartupLocation="CenterScreen" Icon="/TLAgent.Ribbon.App.Demo;component/Images/usergroup.ico">
        
        <Grid x:Name="layoutRoot">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Fluent:Ribbon Grid.Row="0">
                <!--Add QuickAccess-->
                <Fluent:Ribbon.QuickAccessItems>
                    <Fluent:QuickAccessMenuItem Target="{Binding ElementName=ButtonGreen}"/>
                    <Fluent:QuickAccessMenuItem Target="{Binding ElementName=ButtonGray}"/>
                </Fluent:Ribbon.QuickAccessItems>
                <!--Add Tabs-->
                <Fluent:RibbonTabItem Header="Home" ReduceOrder="(P),(P),(P),(P),(P)">
                    <Fluent:RibbonGroupBox Header="Add / Remove">
                        <Fluent:Button Header="Add" Command="{Binding AddFunctionCommand}" Icon="ImagesGreen.png" LargeIcon="ImagesGreenLarge.png" Name="ButtonGreen" />
                        <Fluent:Button Header="Remove" Command="{Binding OpenCommand}" Icon="ImagesGray.png" LargeIcon="ImagesGrayLarge.png" Name="ButtonGray" />
                    </Fluent:RibbonGroupBox>
                    <Fluent:RibbonGroupBox Header="Modify">
                        <Fluent:Button Header="Add" Command="{Binding AddFunctionCommand}" Icon="ImagesGreen.png" LargeIcon="ImagesGreenLarge.png" Name="ButtonGreen1" />
                        <Fluent:Button Header="Remove" Command="{Binding OpenCommand}" Icon="ImagesGray.png" LargeIcon="ImagesGrayLarge.png" Name="ButtonGray1" />
                    </Fluent:RibbonGroupBox>
                </Fluent:RibbonTabItem>
                
                <Fluent:RibbonTabItem Header="用户管理" ReduceOrder="(P),(P),(P),(P),(P)">
                    <Fluent:RibbonGroupBox Header="User Management">
                        <Fluent:Button Header="New User"  Icon="ImagesPink.png" LargeIcon="ImagesPinkLarge.png" Name="ButtonAddUser" />
                        <Fluent:Button Header="Modify User" Icon="ImagesOrange.png" LargeIcon="ImagesOrangeLarge.png" Name="ButtonModiryUser" />
                    </Fluent:RibbonGroupBox>
                </Fluent:RibbonTabItem>
                <!--Backstage Items-->
                <Fluent:Ribbon.Menu>
                    <Fluent:Backstage Background="Gray">
                        <Fluent:BackstageTabControl>
                            <Fluent:Button Header="退出系统" Command="{Binding ExitSystemCommand}" Icon="Imagesclose.png"/>
                        </Fluent:BackstageTabControl>
                    </Fluent:Backstage>
                </Fluent:Ribbon.Menu>
    
            </Fluent:Ribbon>
    
            <ad:DockingManager x:Name="dockManager" Grid.Row="1">
                <ad:DockingManager.Theme>
                    <ad:ExpressionBlueTheme/>
                </ad:DockingManager.Theme>
                <ad:LayoutRoot>
                    <ad:LayoutPanel Orientation="Vertical">
                        <ad:LayoutDocumentPane/>
                        <ad:LayoutAnchorablePane Name="ToolsPane" DockHeight="150">
                        </ad:LayoutAnchorablePane>
                    </ad:LayoutPanel>
                </ad:LayoutRoot>
            </ad:DockingManager>
            <StatusBar VerticalAlignment="Bottom" Height="23" Grid.Row="2" >
                <StatusBarItem VerticalContentAlignment="Center">
                    <TextBlock x:Name="TxtMessage" Foreground="{Binding ForeColor}" FontWeight="Bold" Text="{Binding ExecuteMessage}"/>
                </StatusBarItem>
            </StatusBar>
        </Grid>
        <!--<Window.DataContext>
            <vm:WorkspaceViewModel />
        </Window.DataContext>-->
    </Fluent:RibbonWindow>

    ViewModel源码:

    /************************************************************************
    
       AvalonDock
    
       Copyright (C) 2007-2013 Xceed Software Inc.
    
       This program is provided to you under the terms of the New BSD
       License (BSD) as published at http://avalondock.codeplex.com/license 
    
       For more features, controls, and fast professional support,
       pick up AvalonDock in Extended WPF Toolkit Plus at http://xceed.com/wpf_toolkit
    
       Stay informed: follow @datagrid on Twitter or Like facebook.com/datagrids
    
      **********************************************************************/
    
    using System;
    using System.ComponentModel;
    using System.Linq;
    using System.Windows.Media;
    using Microsoft.Practices.Prism.Commands;
    using Microsoft.Practices.Prism.ViewModel;
    using System.Windows;
    using TLAgent.WPF.Theme;
    using Xceed.Wpf.AvalonDock;
    using Xceed.Wpf.AvalonDock.Layout;
    
    namespace TLAgent.Ribbon.App.Demo
    {
        class WorkspaceViewModel : NotificationObject
        {
            public DelegateCommand AddFunctionCommand { get; set; }
    
            public DelegateCommand ExitSystemCommand { get; set; }
    
            public DelegateCommand OpenCommand { get; set; }
    
            private  DockingManager _dockingManager; 
    
            public WorkspaceViewModel()
            {
               _dockingManager = MainWindow.DockingManager;
    
                AddFunctionCommand = new DelegateCommand(this.OnNew);
    
                ExitSystemCommand = new DelegateCommand(this.OnExit);
    
                OpenCommand = new DelegateCommand(this.OnOpen);
    
            }
    
            private void OnOpen()
            {
                //string frameworkPath = string.Format("/Fluent;component/Themes/Office2010/{0}.xaml", ThemeStyle.Silver);//主框架的样式文件
                //Application.Current.Resources.MergedDictionaries.Clear();
                //设置界面控件的样式
                //设置界面框架的样式
                //Application.Current.Resources.MergedDictionaries.Add((ResourceDictionary)(Application.LoadComponent(new Uri(frameworkPath, UriKind.RelativeOrAbsolute))));
            }
    
            private string _executeMessage;
    
            public string ExecuteMessage
            {
                get { return _executeMessage; }
                set { _executeMessage = value;
                this.RaisePropertyChanged("ExecuteMessage");
                }
            }
            
            private Brush _foreColor;
    
            public Brush ForeColor
            {
                get { return _foreColor; }
                set
                {
                    _foreColor = value;
                    this.RaisePropertyChanged("ForeColor");
                }
            }
            
    
            private void OnNew()
            {
                string functionName = "项目管理";
                CreateSystemTab(functionName);
                ForeColor = new SolidColorBrush(Colors.White);
    
                var leftAnchorGroup = _dockingManager.Layout.LeftSide.Children.FirstOrDefault();
                if (leftAnchorGroup == null)
                {
                    leftAnchorGroup = new LayoutAnchorGroup();
                    _dockingManager.Layout.LeftSide.Children.Add(leftAnchorGroup);
                }
                
                leftAnchorGroup.Children.Add(new LayoutAnchorable() { Title = "New Anchorable" });
                ExecuteMessage = "成功新建,Tabs:" + functionName;
            }
    
            private void CreateSystemTab(string tabName)
            {
                var firstDocumentPane =_dockingManager.Layout.Descendents().OfType<LayoutDocumentPane>().FirstOrDefault();
                if (firstDocumentPane != null)
                {
    
                    LayoutDocument doc2 = new LayoutDocument();
                    AddUserWindow control1 = new AddUserWindow();
                    doc2.Title = tabName;
                    doc2.Content = control1;
                    doc2.IsActive = true;
                    firstDocumentPane.Children.Add(doc2);
    
                }
            }
    
            private void OnExit()
            {
                MessageBoxResult result = MessageBox.Show("确定要退出系统吗?", "确认消息", MessageBoxButton.OKCancel, MessageBoxImage.Question);
                if (result == MessageBoxResult.OK)
                {
                    Application.Current.Shutdown();
                    var serializer = new Xceed.Wpf.AvalonDock.Layout.Serialization.XmlLayoutSerializer(_dockingManager);
                    serializer.Serialize(@".AvalonDock.config");
                }
            }
            public event PropertyChangedEventHandler PropertyChanged;
        }
    }

    更换主题:提供统一的接口就可以实现整合框架和控件主题更换。

    /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : RibbonWindow
        {
            public static DockingManager DockingManager;
    
            public MainWindow()
            {
                InitializeComponent();
                DockingManager = dockManager;
                ThemeManager.ChangeTheme(dockManager, ThemeStyle.Black);//更换主题接口
                this.DataContext = new WorkspaceViewModel();
                this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
                this.Unloaded += new RoutedEventHandler(MainWindow_Unloaded); 
            }

    项目解决方案图:

    project

    现在只稍微提一下,后续有时间再把更详细的设计方法说明。

    源码提供上给大家玩一玩~~。

  • 相关阅读:
    我修改/收藏的CSDN知识.(asp.net JavaScript)
    哪里摔倒就在哪里躺下
    显示存储过程的名称、创建时间、修改时间
    Flash Builder 初试(二)绑定和双向绑定
    C#支持中文的格式化字符长度方法
    Flash Builder 初试(一)信息提示窗口
    Flash Builder 初试(三) 使用摄像头
    Null Object 模式
    开放封闭原则(OCP)
    面向对象设计5大准则
  • 原文地址:https://www.cnblogs.com/aganqin/p/3265223.html
Copyright © 2020-2023  润新知