2009-10-12 37 views
11

Tôi có C# ComboBox bằng cách sử dụng WPF. Tôi có mã thực thi khi kích hoạt GotFocus của ComboBox. Vấn đề là sự kiện GotFocus được thực thi mỗi lần lựa chọn được thực hiện từ ComboBox. Ví dụ: GotFocus được thực thi khi bạn lần đầu tiên nhấp vào ComboBox và sau đó khi bạn thực hiện lựa chọn ngay cả khi bạn chưa nhấp vào bất kỳ điều khiển nào khác.C# ComboBox GotFocus

Có thể ngăn sự kiện này kích hoạt nếu lựa chọn đang được thực hiện trong danh sách hoặc có cờ hoặc điều gì khác trong trình xử lý sự kiện có thể được sử dụng để xác định xem xử lý sự kiện GotFocus có được kích hoạt hay không của người dùng chọn một mục trong danh sách?

+0

thông tin tốt trong câu hỏi này khác. http://stackoverflow.com/questions/830510/issue-with-wpf-focus [link] (http://stackoverflow.com/questions/830510/issue-with-wpf-focus) – Mikeb

Trả lời

0

Tôi không quá nóng trên WPF; nhưng nếu bạn đang cố gắng phát hiện những thay đổi trong danh sách (bấm vào giá trị mới vv), bạn có thể sử dụng các sự kiện SelectedIndexChanged ..

Mặt khác, nếu bạn thực sự muốn biết đơn giản khi điều khiển được tập trung, có thể bạn lọc nó bằng cách nói điều gì đó như;

if (combo1.Focused && combo1.SelectedIndex == -1) 
{ 
    ... 
} 

..? Nó thực sự phụ thuộc vào những gì bạn đang cố gắng để phát hiện, chính xác.

13

Bạn có thể giải quyết vấn đề này với xác minh tiếp theo:

private void myComboBox_GotFocus(object sender, RoutedEventArgs e) 
{ 
    if (e.OriginalSource.GetType() == typeof(ComboBoxItem)) 
     return; 
    //Your code here 
} 

Mã này sẽ lọc tất cả các sự kiện tập trung từ các mặt hàng (vì họ sử dụng sự kiện định tuyến bong bóng). Nhưng có một vấn đề khác - hành vi cụ thể của WPF ComboBox tập trung: khi bạn mở danh sách thả xuống với các mục ComboBox của bạn mất tập trung và các mục nhận được. Khi bạn chọn một số mục - mục mất tiêu điểm và ComboBox sẽ quay lại. Danh sách thả xuống giống như một điều khiển khác. Bạn có thể thấy điều này bằng cách mã đơn giản:

private void myComboBox_GotFocus(object sender, RoutedEventArgs e) 
{ 
    if (e.OriginalSource.GetType() != typeof(ComboBoxItem)) 
    { 
     Trace.WriteLine("Got " + DateTime.Now); 
    } 
} 

private void myComboBox_LostFocus(object sender, RoutedEventArgs e) 
{ 
    if (e.OriginalSource.GetType() != typeof(ComboBoxItem)) 
    { 
     Trace.WriteLine("Lost " + DateTime.Now); 
    } 
} 

Vì vậy, bạn sẽ nhận được ít nhất hai sự kiện nào tập trung: khi bạn chọn ComboBox và khi bạn chọn một cái gì đó trong nó (tập trung sẽ trở lại ComboBox).

Để lọc tiêu điểm được trả về sau khi chọn mục, bạn có thể thử sử dụng các sự kiện DropDownOpened/DropDownClosed với một số cờ trường.

Vì vậy, các mã cuối cùng với chỉ 1 trường hợp nhận được tập trung:

private bool returnedFocus = false; 

private void myComboBox_GotFocus(object sender, RoutedEventArgs e) 
{ 
    if (e.OriginalSource.GetType() != typeof(ComboBoxItem) && !returnedFocus) 
    { 
     //Your code. 
    } 
} 

private void myComboBox_LostFocus(object sender, RoutedEventArgs e) 
{ 
    if (e.OriginalSource.GetType() != typeof(ComboBoxItem)) 
    { 
     ComboBox cb = (ComboBox)sender; 
     returnedFocus = cb.IsDropDownOpen; 
    } 
} 

Chọn từ ví dụ này những gì bạn thực sự cần hơn cho ứng dụng của bạn.

+0

Cảm ơn bạn rất nhiều vì đã lời giải thích tuyệt vời! –

+0

Cảm ơn bạn rất nhiều ... –

0

Một giải pháp khác được sử dụng là để xác định xem phần tử tập trung mới có phải là một mục hiện có trong combobox hay không. Nếu đúng thì sự kiện LostFocus sẽ không được thực hiện, vì combobox vẫn có tiêu điểm. Nếu không, một phần tử bên ngoài combobox sẽ nhận được tiêu điểm.

Trong mã snipplet dưới đây tôi đã thêm các chức năng trong một lớp tùy chỉnh combobox

public class MyComboBox : System.Windows.Controls.Combobox 
{ 
    protected override void OnLostFocus(RoutedEventArgs e) 
    { 
     //Get the new focused element and in case this is not an existing item of the current combobox then perform a lost focus command. 
     //Otherwise the drop down items have been opened and is still focused on the current combobox 
     var focusedElement = FocusManager.GetFocusedElement(FocusManager.GetFocusScope(this)); 
     if (!(focusedElement is ComboBoxItem && ItemsControl.ItemsControlFromItemContainer(focusedElement as ComboBoxItem) == this)) 
     { 
      base.OnLostFocus(e); 
      /* Your code here... */ 
     } 
    } 
}