This article is currently in the process of being translated into Korean (~98% done).
Tab Order
여러분은 프로그래밍을 공부하고 있을 정도로 컴퓨터를 오래 써온 사람들이니, 분명 Tab 키를 통해서 window/dialog 사이를 오갈 수 있다는 사실을 알고 있을 것입니다. 이 기능을 통해서 여러분은 마우스를 이용하지 않고도, 모든 양식을 키보드만으로 채울 수 있습니다.
WPF 또한 이 기능을 지원합니다. 오히려 더 할 정도이죠. WPF는 Tab 키를 눌렀을 때, 어떤 순서로 필드 사이를 오갈지 자동으로 할당해줍니다. 따라서 일반적으로 여러분들이 이것을 걱정할 일은 없죠. 하지만 때때로 여러분들의 Window/dialog 디자인에 따라서, WPF 가 자동으로 할당한 순서가 썩 바람직하지 않을 수 있습니다. 또한 몇몇 컨트롤들에 대해서는 Tab 키를 통해 접근하기 원치 않을 수도 있습니다. 하나 예시를 들어보죠.
이 Dialog 는 그리드로 이루어져있습니다. 중간이 나뉘어져 있고, 좌 우로 StackPanel 들이 있죠. 그리고 StackPanel 들은 각각 Label 들과 TextBox 들을 갖고 있습니다. 기본 Tab Order 전략은 Window 의 첫번째 컨트롤부터 시작해서, 해당 컨트롤 안에 속한 자식 컨트롤 사이를 거치고, 다음 컨트롤로 넘어가는 것입니다. Dialog 가 현재 세로 방향 StackPanel 들로 구성되어있기 때문에, 이 경우 First name 필드부터 시작해서 Street name 필드로 이동하고, 그 다음은 City 필드로 이동할 것입니다. 뒤이어 2번째 StackPanel 로 이동하여, Last name 와 Zip code 필드로 이동합니다. 2번째 StackPanel 에서의 Tabbing 이 전부 끝나고 나면, 마지막의 두 버튼에 도착할 것입니다.
하지만 이 Dialog 에 대해서 저는 이러한 동작이 마음에 들지 않습니다. 대신 Tab 을 통해서 First name 에서 Last name 로 이동하도록 하고, (그러니까 기본적으로 세로로 움직이기보다는 좌에서 우로 움직이도록) City 에는 Tab 을 통해 이동할 수 없기를 원합니다. 왜냐하면 이 필드는 Zip code 필드에 의해 자동적으로 채워지며, 따라서 Readonly 필드가 되길 원하기 때문입니다. 이를 위해서, 저는 TabIndex 와 IsTabStop 라는 두 Property 를 사용하고자 합니다. TabIndex 는 Tab Order 를 정의하는데 사용되며, IsTabStop 는 Tabbing 하는 도중에 이 필드에 들어오지 못하도록 강제합니다. 다음은 이 Dialog 를 만들기 위한 XAML 입니다.
<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>
TabIndex property 를 이용해서, 얼마나 간단하게 Tab Order 를 지정할 수 있는지와 IsTabStop property 를 이용해서 City 필드에 Tab 되는 것을 얼마나 쉽게 막을 수 있는지에 주목해주세요. Dialog 에 Tab Order 를 넣는 것이 이렇게나 쉽답니다!
요약
Tab Order 를 관리하는 것은 아주 중요한 일입니다. 다행인 것은 WPF 가 여러분을 위해 적당한 tab order 를 자동으로 지정해준다는 점이죠. 하지만 때때로 위의 예시처럼 TabIndex , IsTabStop property 를 이용해 이를 조정해야하는 때가 있답니다.