2015-04-14 11 views
25

Khi một ComboBox có một số lượng lớn các mặt hàng, thả xuống của nó sẽ trở thành cuộn. Khi người sử dụng gọi thả xuống này, và di chuyển con trỏ chuột để nhập các giới hạn của thả xuống từ phía dưới, thả xuống ngay lập tức cuộn một hoặc nhiều mục xuống danh sách (từ goobering: cũng xảy ra khi thoát khỏi giới hạn thông qua cạnh đáy).Ngăn chặn di chuyển khi chuột vào WPF ComboBox thả xuống

di chuyển này không trực quan, như danh sách không di chuyển lên khi bước vào giới hạn từ phía trên.

Làm cách nào để vô hiệu hóa hành vi cuộn tự động?

Trong Visual Studio hành vi này có thể quan sát qua menu thả xuống thành viên vào trình soạn thảo mã của thanh điều hướng (CTRL +F2).

+2

Để làm rõ hành vi, điều này dường như bắn bất cứ khi nào con trỏ di chuyển qua ranh giới thấp nhất của ComboBox thả xuống * trong cả hai hướng *, từ trên xuống dưới hoặc từ trên xuống dưới. – goobering

+0

Bạn đang chạy phiên bản .NET nào? – David

+0

@Aravol .NET 4.5 – JoeGaggler

Trả lời

12

One cách để giải quyết vấn đề này là sử dụng Hành vi (hoặc giống như thuộc tính đính kèm giống hành vi) để đăng ký sự kiện RequestBringIntoView của ComboBoxItems và sau đó đặt RequestBringIntoViewEventArgs.Handled thành true. Điều này cũng có thể được thực hiện trên quy mô nhỏ bằng cách sử dụng EventSetter và codebehind.

<Style TargetType="ComboBoxItem">      
    <EventSetter Event="RequestBringIntoView" Handler="OnRequestBringIntoView"/> 
</Style> 

private void OnRequestBringIntoView(object sender, RequestBringIntoViewEventArgs e) 
{ 
    //Allows the keyboard to bring the items into view as expected: 
    if (Keyboard.IsKeyDown(Key.Down) || Keyboard.IsKeyDown(Key.Up)) 
     return;    

    e.Handled = true;    
} 

Sửa

tôi thấy rằng bạn có thể nhận được tác dụng tương tự bằng cách xử lý sự kiện RequestBringIntoView trên ItemsPanel chứ không phải là mặt hàng mình. Nhưng cùng một kết quả:

<ComboBox.ItemsPanel> 
    <ItemsPanelTemplate> 
     <StackPanel RequestBringIntoView="OnRequestBringIntoView"/> 
    </ItemsPanelTemplate> 
</ComboBox.ItemsPanel> 
+0

Không phải trên 'ComboBox' chính nó - như đã được viết nó đã được tại' ComboBoxItem'.Bạn có thể đặt cùng một bản demo nhanh cho thấy nó hoạt động bằng cách thêm 'ComboBoxItems' vào comboBox và kết nối với sự kiện của họ một cách rõ ràng. Nó hoạt động. –

+1

Tôi hiểu. Mã này không tránh cuộn cho các sự kiện chuột. Cần có thêm logic để cho phép cuộn cho các sự kiện bàn phím như người dùng mong đợi, nhưng mã này trả lời câu hỏi ban đầu của tôi. – JoeGaggler

+1

@JoeGaggler Tôi thấy rằng nó cũng hoạt động từ sự kiện 'ItemsPanel' - làm giảm số lượng eventHandlers được nối. –

4

Từ những gì tôi có thể nói điều này dường như được gây ra bởi các mục ở dưới cùng của ánh sáng được "một phần hiển thị", trong đó một mục được cắt ngắn bởi container. Khi chuột di chuyển qua một mục như WPF này, cuộn toàn bộ mục để xem, đôi khi có thể để lại một phần khác ở phía dưới.

Trong Winforms điều này có thể được cố định bằng cách thiết lập .IntegralHeight, nhưng không có tài sản như vậy tồn tại trong WPF từ những gì tôi có thể nói. Nếu tất cả các mục trong combobox của bạn có cùng chiều cao, bạn có thể liên kết chiều cao của danh sách combobox với bội số của chiều cao mục, ví dụ: hiển thị các mục cao 10 x 20px, đặt thành 200.

+0

Đây là một lý thuyết tuyệt vời, nhưng nó đã không xuất hiện để làm việc khi tôi đã thử nó ra. Tôi đã có thể đặt chiều cao mục một cách rõ ràng bằng cách sử dụng thuộc tính 'ItemTemplate', sau đó đặt' MaxDropDownHeight' thành một tích phân của chiều cao mục. Hành vi vẫn xảy ra khi di chuyển chuột lên đường viền của menu thả xuống thả xuống. Tôi cũng đã cố gắng điều chỉnh chiều cao +/- 1px để đảm bảo rằng không có vấn đề nào khác. – JoeGaggler

0

Câu trả lời được chọn từ Andrew Hanlon tránh danh sách để cuộn đến mục đã chọn khi mở. Tôi cũng có để thêm video này vào xử lý sự kiện ("danh sách" là ComboBox):

private void OnRequestBringIntoView(object sender, RequestBringIntoViewEventArgs e) 
{ 
    //Allows the keyboard to bring the items into view as expected: 
    if (Keyboard.IsKeyDown(Key.Down) || Keyboard.IsKeyDown(Key.Up)) 
     return; 

    // Allows to bring the selected item into view: 
    if (((ComboBoxItem)e.TargetObject).Content == list.SelectedItem) 
     return; 

    e.Handled = true; 
} 
Các vấn đề liên quan