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出界面。

由於剛剛學習,如有我哪里有不對或者你有更好的建議,歡迎討論。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM