• WPF仿Word头部格式,涉及DEV RibbonControl,NarvbarControl,ContentPresenter,Navigation


    时隔1个月,2015/06/17走进新的环境。

    最近一个星期在学习仿Word菜单栏的WPF实现方式,废话不多说,先看一下效果。

    打开界面后,默认选中【市场A】,A对应的菜单栏,如上图,

    选择【市场B】后讲改变菜单栏,和B相应的界面。

    要实现上述的功能,要怎么解决?

    实际上,每个界面都可以看成有三部分组成,顶部的DEV.RibbonControl,左侧的DEV.NavbarControl,和中间显示主要界面C部分。

    NavBarControl中包含多个NavBarItem,当切换NavBarItem时,就加载相应的子界面到C处。但,除了MainWindow完整包含这几个部分外,其他子界面都不一定。

     

    下面,就围绕这3个部分展开。

    1、MainWindow.xaml

    <dxr:DXRibbonWindow  x:Class="WPFOptimizeTry.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
            xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
            xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
            xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
            xmlns:dxn="http://schemas.devexpress.com/winfx/2008/xaml/navbar"
            xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
            xmlns:dxrt="http://schemas.devexpress.com/winfx/2008/xaml/ribbon/themekeys"
            xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
            xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
            xmlns:dxwuin="http://schemas.devexpress.com/winfx/2008/xaml/windowsui/navigation"
            xmlns:dxnt="http://schemas.devexpress.com/winfx/2008/xaml/navbar/themekeys"
            xmlns:local="clr-namespace:WPFOptimizeTry"
            xmlns:sys="clr-namespace:System;assembly=mscorlib"
            Title="优化尝试用例"
            Height="900" Width="1300"
            WindowStartupLocation="CenterScreen"
            UseLayoutRounding="True"  
            DataContext="{dxmvvm:ViewModelSource Type=local:MainWindowViewModel}"      
                         Icon="pack://application:,,,/WPFOptimizeTry;component/demoicon.ico" >
    
        <dxmvvm:Interaction.Behaviors>
            <dxmvvm:CurrentWindowService />
            <dx:DialogService/>
        </dxmvvm:Interaction.Behaviors>
        <dxb:BarManager Name="barManager">
            <dxb:BarManager.Items>
                <dxr:RibbonGalleryBarItem x:Name="ribbonGalleryBarItem1">
                    <dxmvvm:Interaction.Behaviors>
                        <dxr:RibbonGalleryItemThemeSelectorBehavior/>
                    </dxmvvm:Interaction.Behaviors>
                    <dxr:RibbonGalleryBarItem.Gallery>
                        <dxb:Gallery ItemGlyphSize="30,24" HoverGlyphSize="48,48"/>
                    </dxr:RibbonGalleryBarItem.Gallery>
                </dxr:RibbonGalleryBarItem>
                <dxb:BarCheckItem x:Name="layoutNormal" IsChecked="{Binding IsExpanded, ElementName=navPanelView, Mode=TwoWay}"
                                  Glyph="pack://application:,,,/WPFOptimizeTry;component/Images/normal.png" GlyphSize="Small"/>
                <dxb:BarCheckItem x:Name="layoutReading"
                                  IsChecked="{Binding IsExpanded, ElementName=navPanelView, Mode=TwoWay, Converter={StaticResource BooleanNegationConverter}}" 
                                  Glyph="pack://application:,,,/WPFOptimizeTry;component/Images/reading.png" GlyphSize="Small"/>
    
            </dxb:BarManager.Items>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <dxr:RibbonControl RibbonStyle="Office2010" x:Name="ribbon" AllowCustomization="False">
                    <!--ApplicationMenu可以先忽略-->
                    <dxr:RibbonControl.ApplicationMenu>
                        <dxr:BackstageViewControl SelectedTabIndex="{Binding DefaultBackstatgeIndex, Mode=TwoWay}" 
                                                  IsOpen="{Binding IsBackstageOpen, Mode=TwoWay}">
                            <dxr:BackstageViewControl.Items>
                                <dxr:BackstageTabItem Content="个人账户"  >
                                </dxr:BackstageTabItem>
                                <dxr:BackstageTabItem  Content="订单查询" IsEnabled="{Binding HasPrinting, Mode=OneWay}">
                                </dxr:BackstageTabItem>
                                <dxr:BackstageButtonItem  Content="授信查询" Command="{Binding ExitCommand}" />
                            </dxr:BackstageViewControl.Items>
                        </dxr:BackstageViewControl>
                    </dxr:RibbonControl.ApplicationMenu>
                    <!--RibbonDefaultPageCategory 主界面默认显示的菜单,像Word里面可能先默认显示-->
                    <dxr:RibbonDefaultPageCategory>
                        <dxr:RibbonPage Caption="主页" >
                            <dxr:RibbonPageGroup Caption="个人账户" ShowCaptionButton="False">
                                <dxb:BarButtonItem Content="修改" x:Name="btnModify"  RibbonStyle="Large"
                                                   Glyph="pack://application:,,,/WPFOptimizeTry;component/Images/WordProcessing.png"
                                                   Command="{Binding ModifyCommand}" ></dxb:BarButtonItem>
                            </dxr:RibbonPageGroup>
                            <dxr:RibbonPageGroup Caption="XXXX" ShowCaptionButton="False">
                                <dxb:BarButtonItem Content="MMM" x:Name="btnM"  RibbonStyle="Large"
                                                   Glyph="pack://application:,,,/WPFOptimizeTry;component/Images/WordProcessing.png"
                                                   Command="{Binding MoCommand}" ></dxb:BarButtonItem>
                            </dxr:RibbonPageGroup>
                        </dxr:RibbonPage>
                    </dxr:RibbonDefaultPageCategory>
                </dxr:RibbonControl>
    
                <dxdo:DockLayoutManager Grid.Row="1" Margin="6">
                    <dxdo:LayoutGroup Caption="LayoutRoot">
                        <dxdo:LayoutPanel Caption="WPF Products" ItemWidth="Auto" AllowClose="False" ShowCaption="False" MaxWidth="183" Name="layoutPanel" AllowSizing="{Binding IsExpanded, ElementName=navPanelView}">
                            <dxn:NavBarControl SelectedItem="{Binding SelectedModuleInfo, Mode=TwoWay}" ItemsSource="{Binding Path=ModuleGroups}">
                                <dxmvvm:Interaction.Triggers>
                                    <dxmvvm:EventToCommand EventName="Loaded" Command="{Binding OnModulesLoadedCommand}" />
                                </dxmvvm:Interaction.Triggers>
                                <dxn:NavBarControl.ItemStyle>
                                    <Style TargetType="dxn:NavBarGroup">
                                        <Setter Property="Header" Value="{Binding Path=Title}" />
                                        <Setter Property="ItemsSource" Value="{Binding Path=ModuleInfos}" />
                                        <Setter Property="ItemStyle">
                                            <Setter.Value>
                                                <Style TargetType="dxn:NavBarItem">
                                                    <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                                                    <Setter Property="Content" Value="{Binding Path=Title}" />
                                                    <Setter Property="ImageSource" Value="{Binding Path=Icon}" />
                                                    <Setter Property="Command" Value="{Binding Path=ShowCommand}" />
                                                    <Setter Property="ImageSettings">
                                                        <Setter.Value>
                                                            <dxn:ImageSettings Width="32" Height="32" Stretch="Uniform" StretchDirection="Both" />
                                                        </Setter.Value>
                                                    </Setter>
                                                    <Setter Property="LayoutSettings">
                                                        <Setter.Value>
                                                            <dxn:LayoutSettings ImageDocking="Top"  ImageHorizontalAlignment="Center" TextHorizontalAlignment="Center" ImageVerticalAlignment="Center" TextVerticalAlignment="Center" />
                                                        </Setter.Value>
                                                    </Setter>
                                                </Style>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </dxn:NavBarControl.ItemStyle>
                                <dxn:NavBarControl.View>
                                    <dxn:NavigationPaneView x:Name="navPanelView" IsOverflowPanelVisible="False" IsSplitterVisible="False" />
                                </dxn:NavBarControl.View>
                            </dxn:NavBarControl>
                        </dxdo:LayoutPanel>
                        <dxdo:LayoutPanel AllowClose="False" AllowFloat="False" AllowHide="False" ShowCaption="False" ShowBorder="False" ShowCloseButton="False">
                            <dxwui:NavigationFrame x:Name="documentFrame"  Navigating="OnDocumentFrameNavigating">
                                <dxwui:NavigationFrame.Resources>
                                    <Style TargetType="dxwui:PageAdornerControl">
                                        <Setter Property="Template">
                                            <Setter.Value>
                                                <ControlTemplate TargetType="dxwui:PageAdornerControl">
                                                    <ContentPresenter Content="{TemplateBinding Content}"  />
                                                </ControlTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </dxwui:NavigationFrame.Resources>
                                <dxmvvm:Interaction.Behaviors>
                                    <dxwuin:FrameNavigationService Frame="{Binding ElementName=documentFrame}" />
                                    <dx:DXSplashScreenService SplashScreenType="{Binding SplashScreenType}" />
                                </dxmvvm:Interaction.Behaviors>
                            </dxwui:NavigationFrame>
                        </dxdo:LayoutPanel>
                    </dxdo:LayoutGroup>
                </dxdo:DockLayoutManager>
    
                <dxr:RibbonStatusBarControl x:Name="statusBar" Grid.Row="2">
                    <dxr:RibbonStatusBarControl.RightItemLinks>
                        <dxb:BarCheckItemLink BarItemName="layoutNormal"/>
                        <dxb:BarCheckItemLink BarItemName="layoutReading"/>
                    </dxr:RibbonStatusBarControl.RightItemLinks>
                </dxr:RibbonStatusBarControl>
            </Grid>
        </dxb:BarManager>
    
    </dxr:DXRibbonWindow>
    

        MainWindow.cs

    namespace WPFOptimizeTry 
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : DXRibbonWindow
        {
           public virtual FrameworkElement BindContent { get; set; }
            public MainWindow()
            {
                InitializeComponent();
                if (Height > SystemParameters.VirtualScreenHeight || Width > SystemParameters.VirtualScreenWidth)
                    WindowState = WindowState.Maximized;
                DevExpress.Utils.About.UAlgo.Default.DoEventObject(DevExpress.Utils.About.UAlgo.kDemo, DevExpress.Utils.About.UAlgo.pWPF, this);
            }
    void OnDocumentFrameNavigating(object sender, NavigatingEventArgs e) { if (e.Cancel) return;

    //在Show命令中触发导航事件,在导航时加载子界面, Type type = Type.GetType(new MainWindow().GetType().Namespace + "." + e.Parameter.ToString(), true, true); var temp = Activator.CreateInstance(type); NavigationFrame frame = (sender as NavigationFrame); frame.Content = temp;
                //到这里其实已经加载页面完毕,如果不添加SetMergeWith语句,会将子界面整个加载到C区,再与主界面合并,肉眼能够看到整个程序变化的过程。
    //使用SetMergeWith可以使整个过度很平滑,会让你觉得一开始菜单就在菜单的位置。 FrameworkElement oldContent = (FrameworkElement)frame.Content; if (oldContent != null) { RibbonMergingHelper.SetMergeWith(oldContent, ribbon); RibbonMergingHelper.SetMergeStatusBarWith(oldContent, statusBar); }
               //下面这句话不可缺少, e.Cancel = true; }
    } }

     MainWindowViewModel.cs

    namespace WPFOptimizeTry
    {
        public class MainWindowViewModel
        {
            public virtual IEnumerable<ModuleGroup> ModuleGroups { get; protected set; }
            public virtual ModuleInfo SelectedModuleInfo { get; set; }
            public virtual Type SplashScreenType { get; set; }
            public virtual int DefaultBackstatgeIndex { get; set; }
            public virtual bool HasPrinting { get; set; }
            public virtual bool IsBackstageOpen { get; set; } 
            [Required]
            protected virtual ICurrentWindowService CurrentWindowService { get { return null; } }  
    
            public MainWindowViewModel()
            {
                List<ModuleInfo> modules = new List<ModuleInfo>() 
                {
                    ViewModelSource.Create(() => new ModuleInfo("UCMarketA", this, "市场A")).SetIcon("GridContacts"),
                    ViewModelSource.Create(() => new ModuleInfo("UCMarketB", this, "市场B")).SetIcon("GridTasks"), 
                };
                ModuleGroups = new ModuleGroup[] {  new ModuleGroup("市场列表", modules)  }; 
            }
    
            public void Exit()
            {
                CurrentWindowService.Close();
            }
    
            public void OnModulesLoaded()
            {
                if (SelectedModuleInfo == null)
                {
                    SelectedModuleInfo = ModuleGroups.First().ModuleInfos.First();
                    SelectedModuleInfo.IsSelected = true;
                    SelectedModuleInfo.Show();
                }
              
            }
        }
    //为NavBarControl构造数据源的类 public class ModuleGroup { public ModuleGroup(string _title, IEnumerable<ModuleInfo> _moduleInfos) { Title = _title; ModuleInfos = _moduleInfos; } public string Title { get; private set; } public IEnumerable<ModuleInfo> ModuleInfos { get; private set; } } //一个NavBarItem对应一个ModuleInfo public class ModuleInfo { ISupportServices Parent; public ModuleInfo(string _type, object parent, string _title) { Type = _type; this.Parent = (ISupportServices)parent; Title = _title; } public string Type { get; private set; } public virtual bool IsSelected { get; set; } public string Title { get; private set; } public virtual Uri Icon { get; set; } public ModuleInfo SetIcon(string icon) { this.Icon = AssemblyHelper.GetResourceUri(typeof(ModuleInfo).Assembly, string.Format("Images/{0}.png", icon)); return this; }
    //选中按钮时触发导航事件,至于为什么,为了极大程度上的符合MVVM,这是我暂时能想到的解决问题的唯一办法。 public void Show(object parameter = null) { INavigationService navigationService = Parent.ServiceContainer.GetService<INavigationService>(); navigationService.Navigate(Type, Type, Parent); } } }

     子界面,以B为例。

    MarketB.xaml,子界面中有不同的菜单,所以需要在子界面写B的菜单RibbonControl.

    <UserControl x:Class="WPFOptimizeTry.UCMarketB"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
                 xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
            xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
            xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
            xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
            xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
            xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
            xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
            xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
                 xmlns:local="clr-namespace:WPFOptimizeTry"
                 DataContext="{dxmvvm:ViewModelSource Type=local:UCMarketBViewModel}"
             Height="300" Width="300">
        <UserControl.Resources>
            <ResourceDictionary>
                 
                <!--<local:ItemTypeToBooleanConverter x:Key="itemTypeToBooleanConverter"/>-->
    
                 <Style x:Key="gridControlMVVMStyle" TargetType="{x:Type dxg:GridControl}">
                    <Setter Property="ItemsSource" Value="{Binding ItemsSource}"/>
                    <Setter Property="ColumnsSource" Value="{Binding Columns}"/>
                    <Setter Property="AutoExpandAllGroups" Value="True"/>
                    <Setter Property="SelectedItem" Value="{Binding SelectedItem, Mode=TwoWay}"/>
                    <Setter Property="FilterString" Value="{Binding FilterString, Mode=TwoWay}"/>
                </Style>
                <dxg:GridControl x:Key="printGridControl"  >
                    <dxg:GridControl.View>
                        <dxg:TableView AutoWidth="True"/>
                    </dxg:GridControl.View>
                    <dxg:GridControl.GroupSummary>
                        <dxg:GridSummaryItem SummaryType="Count"/>
                    </dxg:GridControl.GroupSummary>
                </dxg:GridControl>
            </ResourceDictionary>
        </UserControl.Resources>
        <dxmvvm:Interaction.Behaviors>
            <dxmvvm:NotificationService UseWin8NotificationsIfAvailable="False"
                                    PredefinedNotificationTemplate="ShortHeaderAndLongText"/>
        </dxmvvm:Interaction.Behaviors>
        <Grid>
            <dxb:BarManager CreateStandardLayout="False"> 
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions> 
                        <dxr:RibbonControl  DockPanel.Dock="Top" RibbonStyle="Office2010">
                            <dxr:RibbonDefaultPageCategory> 
                                <dxr:RibbonPage Caption="B市场行情" MergeOrder="1">
                                    <dxr:RibbonPageGroup Caption="报价行情">
                                        <dxb:BarButtonItem Content="行情显示" x:Name="btnQuotationlShow"   RibbonStyle="Large"   
                                                   Glyph="pack://application:,,,/WPFOptimizeTry;component/Images/Analytics.png"
                                                   Command="{Binding QuotationlShowCommand}"></dxb:BarButtonItem>
                                        <dxb:BarButtonItem Content="报价成交" x:Name="btnQuotationDeal"  RibbonStyle="Large"
                                                   Glyph="pack://application:,,,/WPFOptimizeTry;component/Images/Tasks/Completed_32x32.png"
                                                   Command="{Binding QuotationDealCommand}" ></dxb:BarButtonItem>
                                    </dxr:RibbonPageGroup>
                                    <dxr:RibbonPageGroup Caption="成交行情">
                                        <dxb:BarButtonItem Content="成交行情" x:Name="btnDealShow"   RibbonStyle="Large"   
                                                   Glyph="pack://application:,,,/WPFOptimizeTry;component/Images/WeatherMap.png"
                                                   Command="{Binding Path=DealShowCommand}"></dxb:BarButtonItem>
                                    </dxr:RibbonPageGroup>
                                </dxr:RibbonPage> 
                            </dxr:RibbonDefaultPageCategory>
                        <dxr:RibbonPageCategory>
                            <dxr:RibbonPage Caption="风控信息查询">
                                <dxr:RibbonPageGroup Caption="授信查询"></dxr:RibbonPageGroup>
                            </dxr:RibbonPage>
                        </dxr:RibbonPageCategory>
                    </dxr:RibbonControl>
                    <dxlc:LayoutControl Margin="0" Padding="0" Grid.Row="1">
                        <Grid Background="Pink" HorizontalAlignment="Center" VerticalAlignment="Center">
                            <TextBlock x:Name="blkB" Text="{Binding Path=BindMarketBContent,Mode=TwoWay}" Grid.Row="1" TextWrapping="Wrap" Foreground="Red" FontSize="36" />
                        </Grid>
                    </dxlc:LayoutControl >
                    <dxr:RibbonStatusBarControl>
                        <dxr:RibbonStatusBarControl.LeftItemLinks>
                            <dxb:BarStaticItemLink BarItemName="summaryCount"/>
                            <dxb:BarItemLinkSeparator/>
                            <dxb:BarButtonItemLink BarItemName="reminders"/>
                        </dxr:RibbonStatusBarControl.LeftItemLinks>
                    </dxr:RibbonStatusBarControl>
                </Grid>
            </dxb:BarManager>
        </Grid>
    </UserControl>
    

     MarketB.cs

    namespace WPFOptimizeTry 
    {
        /// <summary>
        /// UCMarketB.xaml 的交互逻辑
        /// </summary>
        public partial class UCMarketB : UserControl 
        {
            public UCMarketB()
            {
                InitializeComponent();
            } 
    } }

     UCMarketBViewModel.cs

    namespace WPFOptimizeTry 
    {
        public class UCMarketBViewModel
        {
            public virtual string BindMarketBContent { get; set; }
            public  UCMarketBViewModel()
            {
            }
    
            public void DealShow( )
            {
                BindMarketBContent = "成交行情B";
            }
    
            public void QuotationlShow()
            {
                BindMarketBContent = "行情显示";
            }
    
            public void QuotationDeal()
            {
                BindMarketBContent = "成交";
            }
        }
    }
    

    综上,其实并不复杂,主要是写好各个界面、控件的布局,然后就是想好如何Show出界面。

    由于刚刚学习,如有我哪里有不对或者你有更好的建议,欢迎讨论。

  • 相关阅读:
    Oracle Yum源
    Linux Centos7使用ping命令ping不通网络的解决方案
    Oracle 11G DBMS包和类型参考
    (转载)linux下Yum的$releasever和$basearch的取值
    IDEA 配置Tomcat乱码解决方法
    C# .NET Framework 3.5 下 Thread 与 Semaphore 的简单例子
    C# .NET Framework 3.5 下 Task 与 EventWaitHandle 的简单例子
    Notepad ++ 去//注释的方法
    Clip Studio Paint(优动漫)如何提取线稿?
    C# .NET Framework 3.5 下 Task 与 Semaphore 的简单例子
  • 原文地址:https://www.cnblogs.com/YunGy/p/4616797.html
Copyright © 2020-2023  润新知