2013-10-10 16 views
5

Trong chương trình WPF, tôi muốn lấy Focus (bàn phím) hiện tại, lưu trữ và cài lại sau.Lấy và khôi phục lại tiêu điểm bàn phím WPF

Để có được sự tập trung hiện tại ngay bây giờ tôi sử dụng:

DependencyObject focusScope = FocusManager.GetFocusScope(d); 
_lastFocus = FocusManager.GetFocusedElement(focusScope); 

Để thiết lập nó sau này tôi sử dụng:

if (_lastFocus != null) 
{ 
    IInputElement setFocus = _lastFocus; 
    _lastFocus = null; 
    d.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new ThreadStart(delegate 
    { 
    FocusManager.SetFocusedElement(d, setFocus); 
    })); 
} 

này hoạt động một lần. Nhưng nếu tôi thử lại, nó sẽ không hoạt động cho đến khi tôi tạo lại hộp thoại vi phạm mà tôi cố gắng tập trung vào, mặc dù nó thực hiện điều tương tự (tôi truy tìm và thiết lập Focus). Thay vào đó, chính cửa sổ chính sẽ lấy nét.

Tôi từng nghe có hai loại trọng tâm trong WPF, tôi có cần thiết lập một thứ gì đó khác để có được kết quả nhất quán không?

Trả lời

18

Bạn là chính xác. WPF có trọng tâm hợp lý, mà bạn đang sử dụng ở đó và tập trung vào bàn phím. Bạn có thể tìm thấy chi tiết đầy đủ của hai trong trang Focus Overview của MSDN. Từ trang đó:

Keyboard Focus

Keyboard tập trung đề cập đến yếu tố đó hiện đang nhận được đầu vào bàn phím. Có thể chỉ có một phần tử trên toàn bộ máy tính để bàn có tiêu điểm bàn phím. Trong WPF, phần tử có tiêu điểm bàn phím sẽ được đặt IsKeyboardFocused thành true. Thuộc tính tĩnh FocusedElement trên lớp Keyboard nhận phần tử hiện có tiêu điểm bàn phím.

Để phần tử lấy tiêu điểm bàn phím, các thuộc tính Có thể lấy nét và Có thể chia sẻ trên các phần tử cơ sở phải được đặt thành true. Một số lớp, chẳng hạn như lớp cơ sở Panel, có Focusable được đặt thành false theo mặc định; do đó, bạn phải đặt Focusable thành true nếu bạn muốn một phần tử như vậy để có thể lấy tiêu điểm bàn phím.

Có thể lấy tiêu điểm bàn phím thông qua tương tác người dùng với giao diện người dùng, chẳng hạn như tabbing đến một phần tử hoặc nhấp chuột vào các phần tử nhất định. Tiêu điểm bàn phím cũng có thể thu được bằng lập trình bằng cách sử dụng phương pháp Focus trên lớp Keyboard. Phương pháp lấy nét cố gắng tập trung vào tiêu điểm bàn phím yếu tố được chỉ định. Phần tử được trả lại là phần tử có tiêu điểm bàn phím, có thể là một phần tử khác với yêu cầu nếu đối tượng tiêu điểm cũ hoặc mới chặn yêu cầu.

logic Focus

tập trung logic dùng để chỉ FocusManager.FocusedElement trong một phạm vi lấy nét. Phạm vi tiêu điểm là một phần tử theo dõi FocusedElement trong phạm vi của nó. Khi tiêu điểm bàn phím rời khỏi phạm vi lấy nét, phần tử lấy tiêu điểm sẽ mất tiêu điểm bàn phím nhưng sẽ giữ được tiêu điểm hợp lý. Khi tiêu điểm bàn phím quay trở lại phạm vi lấy nét, phần tử lấy tiêu điểm sẽ lấy tiêu điểm bàn phím. Điều này cho phép tập trung vào bàn phím được thay đổi giữa nhiều phạm vi lấy nét nhưng đảm bảo rằng phần tử lấy nét trong phạm vi lấy nét lấy lại tiêu điểm bàn phím khi tiêu điểm trở về phạm vi tiêu điểm.

Có thể có nhiều yếu tố có trọng tâm hợp lý trong một ứng dụng, nhưng chỉ có thể có một phần tử tập trung hợp lý vào một phạm vi tiêu điểm cụ thể.

Một phần tử có tiêu điểm bàn phím có tiêu điểm hợp lý cho phạm vi tiêu điểm mà nó thuộc về.


Trở lại câu hỏi của bạn, các loại khác tập trung mà bạn không sử dụng là Keyboard.Focus. Bạn có thể sử dụng nó như thế này:

Keyboard.Focus(theButtonThatYouWantToFocus); 

Ngoài ra, lưu ý rằng phương pháp UIElement.Focus() sẽ cố gắng thiết lập cả logic bàn phím tập trung vào các yếu tố đó nó được gọi vào. Nó sẽ trả về truenếu tiêu điểm bàn phím và tiêu điểm lôgic được đặt thành thành phần nàyfalsenếu chỉ tập trung hợp lý được đặt thành yếu tố này.


Một phương pháp khác mà bạn có thể sử dụng để tập trung điều khiển là sử dụng FocusManager.FocusedElementAttached Property. Hầu hết mọi người sử dụng này tĩnh và trong trường hợp này, điều này sẽ chỉ làm việc một lần khi xem tải:

<Grid FocusManager.FocusedElement="{Binding ElementName=TextBoxToFocus}"> 
    <TextBox Name="TextBoxToFocus" Text="Focus Me" /> 
<Grid> 

Tuy nhiên, nó thể sử dụng điều này trong một DataTrigger và để thiết lập nó phụ thuộc vào một tùy chỉnh bool bất động sản , trong ví dụ này, IsFocused tài sản:

<Style x:Key="FocusableTextBoxStyle" TargetType="{x:Type TextBox}"> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding IsFocused}" Value="True"> 
      <Setter Property="FocusManager.FocusedElement" 
       Value="{Binding RelativeSource={RelativeSource Self}}" /> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

Vì vậy, bất cứ khi nào tôi đặt IsFocused tài sản để thực từ mô hình xem, bất kỳ phần tử với Style này áp dụng sẽ nhận được tập trung logic. Bây giờ rõ ràng, điều này Style là dành cho điều khiển TextBox, nhưng nó vẫn sẽ hoạt động nếu bạn thay đổi nó thành Control chẳng hạn.

+0

Tuyệt vời! Tôi đã thêm Keyboard.Focus (setFocus) khi đặt tiêu điểm hợp lý và giờ nó hoạt động, cảm ơn rất nhiều! – Sam

+0

Bạn thực sự có thể loại bỏ hoàn toàn mã chụp/khôi phục bằng cách sử dụng [FocusManager.IsFocusScope] (http://msdn.microsoft.com/en-us/library/system.windows.input.focusmanager.isfocusscope. aspx). – Olly

+0

* Một số lớp, chẳng hạn như lớp cơ sở Bảng điều khiển, có Đặt tiêu cự thành false theo mặc định *. Đây là chìa khóa cho tôi. – dotNET

0

Trước tiên, bạn nên sử dụng Keyboard.Clear() và viết Keyboard.Focus("Your Input element") sau đó.

Keyboard.Clear() xóa tham chiếu tiêu điểm của bạn. Sau đó, bạn có thể tập trung vào bất kỳ yếu tố nào trong giao diện của mình.

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