1. 程式人生 > >Zara帶你快速入門WPF(4)---Command與功能區控制元件

Zara帶你快速入門WPF(4)---Command與功能區控制元件

前言:許多資料驅動的應用程式都包含選單和工具欄或功能區控制元件,允許使用者控制操作,在WPF中,也可以使用功能區控制元件,所以這裡介紹選單和功能區控制元件。

一.選單控制元件

在WPF中,選單很容易使用Menu和MenuItem元素建立,如下面程式碼,其中一個主選單和一個次選單,以及一個子選單項列表。

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="檔案">
                <MenuItem Header="首頁"></MenuItem>
                <MenuItem Header="資訊">
                    <MenuItem Header="首頁"></MenuItem>
                </MenuItem>
                <Separator/>
                <MenuItem Header="推出"/>
            </MenuItem>
            <MenuItem Header="檔案">
                <MenuItem Header="首頁"></MenuItem>
                <MenuItem Header="資訊">
                    <MenuItem Header="首頁"></MenuItem>
                </MenuItem>
                <Separator/>
                <MenuItem Header="推出"/>
            </MenuItem>
        </Menu>
    </DockPanel>
</Window>

 執行應用程式,看到的選單如圖:

二.功能區控制元件

  選單控制元件的替代品是功能區控制元件,自Microsoft Office 07是微軟引入新開發的功能區控制元件,引入這個新功能之後不久,Office以前版本的許多使用者都在抱怨在新的UI中找不到操作按鈕了。新Office使用者沒有使用過以前的使用者介面。卻在新的UI中得到了很好的體驗,很容易找到以前版本的使用者難以找到的操作按鈕。

WPF功能區控制元件在System.Windows.Controls.Ribbon名稱空間中,需要引用這個命名控制元件,下面這個示例中我們將要展示一個功能區控制元件的使用。

為了直接可以把快速訪問工具欄中的這些按鈕放到視窗的邊框中,我們需要修改後臺繼承類,這個基類是RibbonWindow  然後再修改下XAML的根節點。

使用Ribbon需要讓專案中引用它,如圖所示:

<RibbonWindow x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <DockPanel>
        <Ribbon DockPanel.Dock="Top">
            <Ribbon.QuickAccessToolBar>
                <RibbonQuickAccessToolBar>
                    <RibbonButton SmallImageSource="one.png"></RibbonButton>
                    <RibbonButton SmallImageSource="one.png"></RibbonButton>
                </RibbonQuickAccessToolBar>
            </Ribbon.QuickAccessToolBar>
            <Ribbon.ApplicationMenu>
                <RibbonApplicationMenu SmallImageSource="one.png">
                    <RibbonApplicationMenuItem Header="Hello"/>
                    <RibbonSeparator/>
                    <RibbonApplicationMenuItem Header="Exit" Command="Close"/>
                </RibbonApplicationMenu>
            </Ribbon.ApplicationMenu>
        </Ribbon>
    </DockPanel>
</RibbonWindow>

  在應用程式選單中,使用RibbonTab元素定義功能區控制元件的內容,RibbonTab元素中包含兩個RibbonGroup元素,每個RibbonGroup中包含RibbonButton,在按鈕中用Label顯示文字,設定SmallImageSource活著LargeImageSource可以配上圖片。

 <RibbonTab Header="Home">
                <RibbonGroup Header="Clipboard">
                    <RibbonButton Command="Paste" Label="yi" LargeImageSource="one.png"/>
                    <RibbonButton Command="Cut" Label="er" LargeImageSource="one.png"/>
                    <RibbonButton Command="Undo" Label="san" LargeImageSource="one.png"/>
                </RibbonGroup>
                <RibbonGroup Header="Show">
                    <RibbonButton  Label="yi" LargeImageSource="one.png"/>
                    <RibbonButton Command="Cut" Label="er" LargeImageSource="one.png"/>
                    <RibbonButton Command="Undo" Label="san" LargeImageSource="one.png"/>
                </RibbonGroup>
            </RibbonTab>

第二個RibbonTab元素僅用於演示可以在功能區使用不同的控制元件,裡面可以放入很多控制元件!

 <RibbonTab Header="Ribben Controla">
                <RibbonGroup Header="Smaples">
                    <RibbonButton Label="Button"/>
                    <RibbonCheckBox Label="Checkbox"/>
                    <RibbonComboBox>
                        <Label>one</Label>
                        <Label>two</Label>
                    </RibbonComboBox>
                    <RibbonTextBox>Text Box</RibbonTextBox>
                    <RibbonSplitButton Label="Split Button">
                        <RibbonMenuItem Header="One"/>
                        <RibbonMenuItem Header="Two"/>
                    </RibbonSplitButton>
                    <RibbonComboBox Label="Combox2" IsEditable="False">
                        <RibbonGallery SelectedValuePath="Content" MaxColumnCount="1" SelectedValue="Green">
                            <RibbonGalleryCategory>
                                <RibbonGalleryItem Content="red" Foreground="Red"/>
                                <RibbonGalleryItem Content="Green" Foreground="Green"/>
                            </RibbonGalleryCategory>
                        </RibbonGallery>
                    </RibbonComboBox>
                </RibbonGroup>
                <RibbonGroup Header="Smaples">
                    <RibbonButton Label="Button"/>
                    <RibbonCheckBox Label="Checkbox"/>
                    <RibbonComboBox>
                        <Label>one</Label>
                        <Label>two</Label>
                    </RibbonComboBox>
                    <RibbonTextBox>Text Box</RibbonTextBox>
                </RibbonGroup>
            </RibbonTab>

效果圖與其對應所示:

三.Commanding

   Commanding是一個WPF概念,它在動作源和執行動作的目標之間建立鬆散耦合,這個概念基於Gang Of Four中的命令模式,在WPF中,事件是緊密耦合的,編譯包含事件引用的XAML程式碼,要求程式碼隱藏已實現一個處理程式的方法,並且編譯期間可用,而對於命令,這個耦合是鬆散的。

注意:命令模式是一種行為設計模式,它分離客戶和命令的接收者,更加適合進行單元測試。

要執行的動作用於命令物件建立,命令實現Icommand介面,wpf使用的命令類是RoutedCommand及其派生類RoutedUiCommand,RoutedUiCommand類定義了一個Icommand介面未定義附加Text屬性,這個屬性可以在使用者介面中用作檔案資訊,ICommand定義Execute()和CanExecute()方法,它們都在物件上執行。

命令源是呼叫命令的物件,命令源實現IcommandSource介面,這種命令源的例子有派生自ButtonBase的按鈕類,HyperLink,KeyBinding,InputBinding,MouseBinging是派生自InputBinding的類,命令源有一個Command屬性,其中就可以指定實現這個Icommand介面的命令物件。

下面我們舉一個例子來說明下命令物件的實現方式,我們需要先講解以下如何定義命令。

四.定義命令

  .NET提供了返回預定義命令的類,ApplicatioNCommands類定義了靜態屬性New、open、Close、Print、Cut、Copy、Paste等這些屬性返回可用於特殊目的的RoutedUiCommand物件。提供了命令的其他類有NavigationCommands和MediaComands,NavigationCommands提供了導航常見命令,如GoTopage、NextPage、PreviousPage、MediaCommand提供的命令。

  定義執行應用程式域並不難,為此建立了一個BooksCommands類,它通過ShowBook與ShowBookList屬性返回了一個RoutedUiCommand,也可以給命令指定一個手勢,如KeyGesture或MouseGesture,這裡指定一個KeyGesture.用ALT修飾B鍵,所以按ALT+B組合鍵可以呼叫這個命令,我們看以下這個方法的具體實現:

using System.Windows.Input;

namespace WpfApp1
{
    public class BooksCommands
    {
        private static RoutedUICommand s_showbook;
        public static ICommand ShowBook =>
            s_showbook ?? (s_showbook = new RoutedUICommand("Show Book", nameof(ShowBook), typeof(BooksCommands)));
        private static RoutedUICommand s_showBooksList;
        public static ICommand ShowBooksList
        {
            get
            {
                if (s_showBooksList==null)
                {
                    s_showBooksList = new RoutedUICommand("Show Book", nameof(ShowBook), typeof(BooksCommands));
                    s_showBooksList.InputGestures.Add(new KeyGesture(Key.B, ModifierKeys.Alt));
                }
                return s_showBooksList;
            }
        }
    }
}

五.定義命令源

每個實現IcommandSource介面的類都可以是命令源,如Button和MenuItem,在前面建立的功能區控制元件中,把Command屬性賦予幾個RibbonButton元素中,如下列程式碼所示:

<Ribbon DockPanel.Dock="Top">
            <Ribbon.QuickAccessToolBar>
                <RibbonQuickAccessToolBar>
                    <RibbonButton SmallImageSource="one.png" Command="local:BooksCommands.ShowBook"/>
                    <RibbonButton SmallImageSource="one.png" Command="local:BooksCommands.ShowBooksList"/>
                </RibbonQuickAccessToolBar>
            </Ribbon.QuickAccessToolBar>
        </Ribbon>

一些常見的預命令,例如ApplicationCommands.Cut、Copy、Paste 也賦予RibbonButton元素的Command屬性,對於域命令的命令直接在Command上寫上這些就好。

六.命令繫結

必須新增命令繫結才能把它們連線到處理程式方法上,這裡在Window元素中定義命令繫結,這樣這些就可以操作所有的視窗元素,執行ApplicactionCommands.Close命令時,會呼叫OnClose,執行BooksCommands.ShowBook命令時,會呼叫OnShowBooks();

    <Window.CommandBindings>
        <CommandBinding Command="Close" Executed="CommandBinding_Executed"/>
    </Window.CommandBindings>
 private void CommandBinding_Executed(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
        {
            Application.Current.Shutdown();
        }

....未完待續我們明天說一下資料繫結 盡情期待