TOC

This article is currently in the process of being translated into Vietnamese (~90% done).

Common interface controls:

The WPF Menu control

Một trong những phần phổ biến nhất của ứng dụng Windows là menu, đôi khi được gọi là menu chính vì thường mỗi ứng dụng chỉ có duy nhất một menu. Menu này rất thiết thực vì nó cung cấp rất nhiều tùy chọn, chiếm rất ít không gian và mặc dù Microsoft đang thúc đẩy sử dụng Ribbon như một sự thay thế hữu hiệu cho menu và thanh công cụ cũ, nhưng chắc chắn Menu vẫn có một vị trí riêng của mình trong Toolbox.

WPF đi kèm với một control để tạo các menu gọi là ... Menu. Haha. Thêm các mục cho nó rất đơn giản - bạn chỉ cần thêm các phần tử MenuItem vào nó và ở mỗi phần tử      MenuItem có thể thêm một loạt các mục con, cho phép tạo các menu phân cấp như rất nhiều ứng dụng Windows mà chúng ta đã biết. Giờ, cùng nhảy thẳng đến một ví dụ mà chúng tôi sử dụng Menu:

<Window x:Class="WpfTutorialSamples.Common_interface_controls.MenuSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MenuSample" Height="200" Width="200">
    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_File">
                <MenuItem Header="_New" />
                <MenuItem Header="_Open" />
                <MenuItem Header="_Save" />
                <Separator />
                <MenuItem Header="_Exit" />
            </MenuItem>
        </Menu>
        <TextBox AcceptsReturn="True" />
    </DockPanel>
</Window>

Như trong hầu hết các ứng dụng Windows, menu của tôi được đặt ở sát trên cùng cửa sổ, nhưng để phù hợp với tính linh hoạt của WPF, bạn thực sự có thể đặt control menu bất cứ nơi nào bạn thích, ở bất kỳ chiều rộng hoặc chiều cao nào bạn muốn.

Tôi đã thiết lập một mục cấp cao nhất, với 4 mục con và dấu phân cách. Tôi sử dụng thuộc tính Header để định nghĩa tên của mục và bạn nên chú ý dấu gạch dưới trước ký tự đầu tiên của mỗi tên. Nó báo cho WPF sử dụng ký tự đó làm phím shortcut, có nghĩa là người dùng có thể nhấn phím Alt + ký tự đã cho để kích hoạt mục menu. Nó hoạt động ở tất cả các mục từ cấp cao nhất xuống phân cấp, nghĩa là trong ví dụ này tôi có thể nhấn Alt , sau đó F và sau đó N để kích hoạt mục New

Icons và checkboxes

Hai tính năng phổ biến của một mục menu là biểu tượng, thường dùng để dễ xác định mục menu, xem nó là gì, và để dễ nhận biết được mục menu, có thể bật và tắt một tính năng cụ thể. MenuItem của WPF hỗ trợ cả hai và rất dễ sử dụng:

<Window x:Class="WpfTutorialSamples.Common_interface_controls.MenuIconCheckableSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MenuIconCheckableSample" Height="150" Width="300">
    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_File">
                <MenuItem Header="_Exit" />
            </MenuItem>
            <MenuItem Header="_Tools">
                <MenuItem Header="_Manage users">
                    <MenuItem.Icon>
                        <Image Source="/WpfTutorialSamples;component/Images/user.png" />
                    </MenuItem.Icon>
                </MenuItem>
                <MenuItem Header="_Show groups" IsCheckable="True" IsChecked="True" />
            </MenuItem>
        </Menu>
        <TextBox AcceptsReturn="True" />
    </DockPanel>
</Window>

Trong ví dụ này, tôi đã tạo một mục cấp cao thứ hai, trong đó tôi đã thêm hai mục: Một mục có sử dụng Icon, dùng thuộc tính Icon với control Image bên trong và một mục tôi sử dụng thuộc tính IsCheckable để cho phép người dùng chọn và bỏ chọn mục này. Tôi còn thêm thuộc tính IsChecked để mục được chọn mặc định. Từ Code-behind, đây là một thuộc tính giống nhau mà bạn có thể biết liệu một mục menu có được chọn hay không.

Sự kiện Clicks

Khi người dùng click vào menu item, thường bạn sẽ muốn nó thực hiện chuyện gì đó. Cách đơn giản nhất là thêm một sự kiện cho MenuItem, như thế này:

<MenuItem Header="_New" Click="mnuNew_Click" />

Trong code-behind bạn cần thêm vài thứ cho mnuNew_Click

private void mnuNew_Click(object sender, RoutedEventArgs e)
{
	MessageBox.Show("New");
}

Làm thế này đi cho ứng dụng đơn giản hơn hoặc khi tạo ra nguyên mẫu cho một thứ gì đó, nhưng cách WPF làm là sử dụng Command cho việc này.

Keyboard shortcuts và Commands

Bạn có thể dễ dàng xử lý sự kiện Click của một mục menu như chúng tôi đã làm ở trên, nhưng cách tiếp cận phổ biến hơn là sử dụng các lệnh của WPF (WPF command). Có rất nhiều thứ cần biết về việc sử dụng và tạo command, nên chúng có nhiều danh mục bài viết riêng trên trang web này, nhưng giờ, tôi có thể nói với bạn rằng có một vài lợi thế khi sử dụng command trong WPF, đặc biệt là kết hợp với Menu hoặc Thanh công cụ.

First of all, they ensure that you can have the same action on a toolbar, a menu and even a context menu, without having to implement the same code in multiple places. They also make the handling of keyboard shortcuts a whole lot easier, because unlike with WinForms, WPF is not listening for keyboard shortcuts automatically if you assign them to e.g. a menu item - you will have to do that manually.

Tuy nhiên, khi sử dụng command, WPF tự động lắng nghe và sẽ tự động phản hồi phím tắt từ bàn phím. Tên (Header) của menu item là tên đặt tự động (mặc dù bạn có thể viết lại nó nếu cần), và InputGestureText cũng hiển thị cho người dùng biết phím tắt nào có thể sử dụng để gọi mục menu cụ thể. Giờ, cùng nhảy thẳng vào một ví dụ về việc kết hợp Menu với các lệnh WPF:

<Window x:Class="WpfTutorialSamples.Common_interface_controls.MenuWithCommandsSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MenuWithCommandsSample" Height="200" Width="300">
    <Window.CommandBindings>
        <CommandBinding Command="New" CanExecute="NewCommand_CanExecute" Executed="NewCommand_Executed" />
    </Window.CommandBindings>
    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_File">
                <MenuItem Command="New" />
                <Separator />
                <MenuItem Header="_Exit" />
            </MenuItem>
            <MenuItem Header="_Edit">
                <MenuItem Command="Cut" />
                <MenuItem Command="Copy" />
                <MenuItem Command="Paste" />
            </MenuItem>
        </Menu>

        <TextBox AcceptsReturn="True" Name="txtEditor" />
    </DockPanel>
</Window>
using System;
using System.Windows;
using System.Windows.Input;

namespace WpfTutorialSamples.Common_interface_controls
{
	public partial class MenuWithCommandsSample : Window
	{
		public MenuWithCommandsSample()
		{
			InitializeComponent();
		}

		private void NewCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = true;
		}

		private void NewCommand_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			txtEditor.Text = "";
		}
	}
}

Nó có thể không hoàn toàn rõ ràng, nhưng bằng cách sử dụng các lệnh command, chúng tôi đã có được rất nhiều thứ thoải mái: Phím tắt, văn bản và InputGestureText trên các mục và WPF tự động bật/tắt các mục tùy thuộc vào việc kích hoạt control và trạng thái của nó. Trong trường hợp này, Cut và Copy bị vô hiệu hóa vì không có văn bản nào được chọn, nhưng Paste được bật, vì Clipboard của tôi không trống!

Và bởi vì WPF biết cách xử lý các lệnh nhất định kết hợp với các điều khiển nhất định, nên trong trường hợp này, các lệnh Cut/Paste/Copy kết hợp với control textbox, chúng tôi thậm chí không phải xử lý các sự kiện thực thi Execute của chúng - chúng hoạt động ngay lập tức! Chúng ta sẽ phải tự viết xử lý cho các lệnh command mới, khi WPF không thể đoán được chúng ta muốn gì khi người dùng kích hoạt nó. Điều này được thực hiện với CommandBindings của Window, tất cả được giải thích chi tiết trong bài viết về các lệnh command.

Summary

Làm việc với điều khiển Menu WPF vừa nhanh vừa dễ, giúp đơn giản hóa việc tạo các phân cấp menu phức tạp và khi kết hợp nó với các lệnh WPF, bạn sẽ có được rất nhiều chức năng thoải mái.

This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!