TOC

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

Control concepts:

Thứ tự tab

Nếu bạn đã làm việc với máy tính đủ lâu để muốn học lập trình, bạn chắc chắn cũng hiểu rằng ban có thể sử dụng phím Tab trên bàn phím để dịch duyển qua lại trong 1 cửa sổ/hộp thoại. Nó cho phép bạn giữ tay trên bàn phím khi điền thông tin trên form hoặc điều gì đó tương tự thay vì phải sử dụng chuột để chọn trường/control tiếp theo.

WPF hỗ trợ hành vi này trực tiếp trên box, và thậm chí tốt hơn: Nó sẽ tự động thiết lập đánh thứ tự khi bạn kéo 1 trường đến 1 trường khác, vì vậy nói chung bạn không có gì phải lo lắng về nó cả. Tuy nhiên, đôi khi thiết kế của của sổ/hộp thoại của bạn gây ra việc WPF dùng thứ tự tab không phù hợp vì nhiều lý do. Cũng vậy khi bạn cũng có thể quyết định những control nhất định nào không nên tham gia vào tứ tự tab. Cho phép tôi minh họa điều này với 1 ví dụ:

Hộp thoại này chứ 1 Grid, tách ở giữa làm 2 phần với mỗi StackPanel trên mỗi bên, chứa các label và textbox. Thứ tự tab mặc định sẽ bắt đầu với control đầu tiên của Window và tab qua mỗi control con tìm thấy trong nó trước khi di chuyển đến control tiếp theo. Vì hộp thoại chứa StackePanel sắp xếp theo chiều dọc, có nghĩa là chúng ta sẽ bắt đầu từ trường First name và sau đó di chuyển tới trường Street name rồi tới trường City, trước khi di chuyển tới StackPanel thứ 2, chứa các trường Last nameZip code. Khi tab khỏi StackPanel thứ 2, hai button cuối cũng sẽ được chuyển đến.

Tuy nhiên, đối với hộp thoại này không phải là hành vi tôi muốn. Thay vào đó tôi muốn tab từ First name đến Last name (căn bản di chuyển chiều ngang thay vì chiều dọc), và trên tất cả tôi không muốn vào trường City khi tab qua form bởi vì nó sẽ được tự động điền dựa trên Zip codetrong hộp thoại thực tế này và vì vậy nó được thiết lập readonly. Để hoàn thành tất cả điều này, tôi sẽ dùng 2 thuộc tính: TabIndexIsTabStop. TabIndex được dùng để định nghĩa thứ tự, trong khi thuộc tính IsTabStop sẽ ép WPF bỏ qua control này khi tab qua lại trong Window. Đây là markup được sử dụng để tạo hộp thoại:

<Window x:Class="WpfTutorialSamples.Control_concepts.TabOrderSample"
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:WpfTutorialSamples.Control_concepts"
mc:Ignorable="d"
Title="TabOrderSample" Height="250" Width="400">
    <Grid Margin="20">
<Grid.ColumnDefinitions>
    <ColumnDefinition Width="*" />
    <ColumnDefinition Width="20" />
    <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
    <RowDefinition Height="*" />
    <RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel>
    <Label>First name:</Label>
    <TextBox TabIndex="0" />
    <Label>Street name:</Label>
    <TextBox TabIndex="2" />
    <Label>City:</Label>
    <TextBox TabIndex="5" IsReadOnly="True" IsTabStop="False" Background="Gainsboro" />
</StackPanel>
<StackPanel Grid.Column="2">
    <Label>Last name:</Label>
    <TextBox TabIndex="1" />
    <Label>Zip Code:</Label>
    <TextBox TabIndex="4" />
</StackPanel>
<Button Grid.Row="1" HorizontalAlignment="Right" Width="80">Add</Button>
<Button Grid.Row="1" Grid.Column="2" HorizontalAlignment="Left" Width="80">Cancel</Button>
    </Grid>
</Window>

Notice how I simply give each relevant control a number in the TabIndex property, and then use the IsTabStop for the TextBox used for the City - it's that simple to control the tab order in a dialog!

Summary

Controlling the tab order of a dialog is very important, but fortunately for us, WPF does a very good job of automatically defining a proper tab order for you. However, in some cases, it will make sense to go in and take control, using the TabIndex and IsTabStop properties, as illustrated in the example above.

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!