2011-12-17 44 views
10

Chúng tôi có ứng dụng dựa trên WPF .NET 4.0 C#. Chúng tôi đã xây dựng giao diện người dùng của chúng tôi từ các định nghĩa XML (không phải XAML) nhưng bên dưới chúng tôi sử dụng một WPF để trình bày giao diện người dùng. Đó là lúc chạy, chúng ta tạo giao diện người dùng WPF dựa trên định nghĩa XML của chúng ta.Điều hướng phím Tab WPF

Chúng tôi gặp sự cố với điều hướng tab. Chúng tôi đặt TabStop, TabIndex, cho điều khiển hộp văn bản và hộp tổ hợp.
Nhưng điều hướng tab không hoạt động. Làm cách nào để điều hướng tab hoạt động cho bố cục này?

enter image description here

+4

thế nào là bạn thiết lập các thuộc tính TabIndex cho điều khiển của bạn trong mã-phía sau cho giao diện này? Bạn cần phải rõ ràng hơn về những gì không hoạt động. Đăng một số mã. – Bernard

+4

Bạn có ý nghĩa gì bởi 'không hoạt động'? Có phải 'bạn nhấn Tab nhưng tiêu điểm sẽ không di chuyển'? Hoặc nó di chuyển, nhưng di chuyển sai? Trong đó có cách nào sai? –

+0

Bạn đã xem lớp [KeyboardNavigation] (http://msdn.microsoft.com/en-us/library/aa969768.aspx#Keyboard_Navigation) chưa? – rfmodulator

Trả lời

8

Bạn nên cố gắng thiết lập một KeyboardNavigation.TabNavigation tài sản gắn liền trên một trong hai Tree kiểm soát của bạn, hoặc sự kiểm soát StackPanel có nguồn gốc, trong trường hợp bạn muốn nút dưới cùng của bạn để cũng tham gia vào một chu kỳ tab:

<controls:CustomStackPanel KeyboardNavigation.TabNavigation="Cycle"> 
<Tree> 
... 
</Tree> 
</controls:CustomStackPanel> 

Bạn thậm chí có thể kết hợp một cách tiếp cận mã-đằng sau bạn, tôi giả định, hiện đang cố gắng sử dụng để kiểm soát hành vi tab bên trong điều khiển Tree, với KeyboardNavigation.TabNavigation để chăm sóc tabbing bên ngoài điều khiển cây.

29

WPF xử lý toàn bộ cây giao diện người dùng dưới dạng một phạm vi Tab duy nhất. Nó không được chia thành các khu vực nhỏ hơn như bạn mong đợi. Điều này bao gồm các điều khiển bên trong UserControls.

Thí dụ, nếu bạn có

<StackPanel> 
    <TextBox Name="TextBox1" /> 
    <MyUserControl /> 
    <TextBox Name="TextBox3" /> 
</StackPanel> 

MyUserControl trông giống như

<MyUserControl> 
    <TextBox Name="TextBox2" /> 
</MyUserControl> 

Chu kỳ tab mặc định sẽ là TextBox1, TextBox2, TextBox3. Điều này là do không có thuộc tính TabIndex được xác định, vì vậy tất cả các điều khiển đều chạy theo thứ tự tab mặc định, là thứ tự mà chúng được thêm vào giao diện người dùng.

Nếu bạn đặt tabIndex trên điều khiển của bạn như dưới đây,

<StackPanel> 
    <TextBox Name="TextBox1" TabIndex="1" /> 
    <MyUserControl TabIndex="2" /> 
    <TextBox Name="TextBox3" TabIndex="3" /> 
</StackPanel> 

tabbing của bạn sẽ thay đổi để TextBox1, TextBox3, TextBox2. Điều này là bởi vì TextBox2 không có một TabIndex được chỉ định, do đó, mặc định được giả định và nó được tabbed để sau khi tất cả các điều khiển khác với một TabIndex quy định có được chu kỳ thông qua.

Cách tôi thường nhận được xung quanh điều này là để ràng buộc các TabIndex điều khiển bên trong UserControl để UserControl.TabIndex.

Ví dụ thêm các ràng buộc sau vào UserControl sẽ làm cho chu kỳ Tab đúng một lần nữa

<MyUserControl> 
    <TextBox Name="TextBox2" TabIndex="{Binding Path=TabIndex, RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}}" /> 
</MyUserControl> 

Tôi thường thích để thiết lập này ràng buộc trong trường hợp Loaded của UserControl thay vì phải nhớ để thiết lập này ràng buộc trên tất cả các điều khiển bên trong UserControl. Tôi chắc rằng cũng có nhiều cách hiệu quả hơn để làm điều này, tuy nhiên vấn đề không xuất hiện thường xuyên đủ để tôi ngồi xuống và dành thời gian nghiên cứu cách sử dụng đúng các phạm vi tab để tránh cách giải quyết này.

5

Không phải là câu trả lời cho mỗi lần nhưng tab WPF cực kỳ khó sử dụng. Yêu cầu thiết lập các thuộc tính TabNavigation, IsTabStop trong Xaml và không quan trọng với phạm vi lấy nét. Tôi đã dành nhiều ngày cố gắng để có được tabbing ngay bằng cách sử dụng Xaml một mình. Tôi sẽ đề nghị để bắt đầu với XML của bạn -> WPF mô hình thực sự nên được Xaml -> WPF!Tuy nhiên tôi sẽ tưởng tượng điều đó là không thể.

Cách này để giải quyết sự cố. Bạn có thể xử lý tabbing trong mã được tạo không? Nếu WPF usercontrols của bạn được tạo ra bởi phần mềm của riêng bạn từ XML của riêng bạn thì tôi khuyên bạn nên đặt một phần tử TabOrder trong XML của bạn và sau đó sử dụng nó để kết nối một sự kiện TabOut.

Nhìn vào mẫu mã sau đây để buộc một hoạt động di chuyển trong mã (Tương tự như tabbing)

// Creating a FocusNavigationDirection object to perform the tab operation 
// values include Next, Previous, First, Last etc... 
FocusNavigationDirection focusDirection = FocusNavigationDirection.Next; 

// MoveFocus takes a TraveralReqest as its argument. 
TraversalRequest request = new TraversalRequest(focusDirection); 

// Gets the element with keyboard focus. 
UIElement elementWithFocus = Keyboard.FocusedElement as UIElement; 

// Change keyboard focus. 
if (elementWithFocus != null) 
{ 
    elementWithFocus.MoveFocus(request); 
} 

Thứ hai dây vào KeyUp (hoặc PreviewKeyUp) trường hợp điều khiển "tabbable" của bạn và nếu phím là tab gọi mã trên để làm tiêu điểm chuyển sang phần tử tiếp theo.

Mẫu mã ở trên về cơ bản sẽ buộc phải viết mã những gì WPF nên làm ra khỏi hộp. Áp phích khác như đã đề nghị tôi sẽ đi qua mã WPF tạo của bạn để xem những gì các giá trị của KeyboardNavigation.IsTabStop và KeyboardNavigation.TabNavigation

Trân trọng,

+0

không chắc chắn về việc xử lý các tab một cách rõ ràng nói chung - có vẻ như một chút hacky. 1 cho các công cụ MoveFocus mặc dù - Tôi thấy tôi cần nó để xử lý một shift + tab cho một điều khiển tùy chỉnh, nơi một số trong những thứ đã thay đổi tầm nhìn của nó. –

0

Hãy thử KeyboardNavigation.TabNavigation = "Once"

Các vấn đề liên quan