2013-08-14 34 views
7

Tôi đã tìm kiếm câu trả lời của Google và đây, vấn đề của tôi có liên quan đến câu hỏi dưới đây, nhưng đủ khác để đảm bảo một câu hỏi mới.WPF: Combobox mất chỉ mục đã chọn sau khi bị ràng buộc Thay đổi bộ sưu tập ItemSource

Combo-box loses selection after collection changes

Về cơ bản, tôi có một combobox WPF được ràng buộc với một lớp ObservableCollection. Lớp này có thêm chức năng để trì hoãn thông báo thay đổi bộ sưu tập nếu tôi cần thực hiện một số thay đổi đối với nó, chẳng hạn như xóa và nạp lại để có được ảnh chụp nhanh của cơ sở dữ liệu.

Ràng buộc combobox của tôi có cả bộ DisplayMemberPath và SelectedValuePath. SelectedValuePath phân giải thành một thuộc tính số nguyên.

Vấn đề là giống như câu hỏi được tham chiếu, khi tôi làm mới các giá trị trong bộ sưu tập bị ràng buộc, ComboBox bị ràng buộc mất lựa chọn của nó và bị trống (SelectedIndex = -1).

Tôi có thể xác nhận rằng sự kiện CollectionChanged không được kích hoạt cho đến khi bộ sưu tập đã được điền lại và có các mục trở lại bên trong nó.

More khó hiểu là nếu tôi làm như sau:

 using (_collection.DelayNotifications()) 
     { 
      var items = _collection.ToArray(); 
      _collection.Clear(); 
      _collection.AddRange(items); 
     } 

Các combobox không không mất giá trị vùng chọn ưng ý.

Điều này cho thấy rằng nó bị hỏng nếu các mục trong bộ sưu tập được thay thế bằng các mục mới được lấy từ cơ sở dữ liệu - tôi có thể chấp nhận điều này nếu tôi không sử dụng liên kết SelectedValuePath, nhưng vì tôi, và bởi vì các giá trị số nguyên như vậy, chắc chắn những gì tôi đang làm nên hoạt động?

Tôi đang sử dụng .NET 3.5 SP1

Bất kỳ ai có ý tưởng nào?

Sửa

Từ những ý kiến ​​dưới đây và trả lời Blam của. Tôi chấp nhận rằng đó là những lý do tại sao lý do tại sao làm việc đó. Nhưng nó không thực sự giúp tôi.

Tôi ràng buộc thuộc tính SelectedValue của Hộp tổ hợp thành thuộc tính Số nguyên trên mô hình chế độ xem của tôi. Nếu tôi đã ràng buộc SelectedItem, tôi sẽ cần phải liên kết với một thuộc tính của kiểu đối tượng đó trên mô hình khung nhìn của tôi - nhưng đó là thuộc tính số nguyên mà tôi thực sự sau đó.

Hiện tại, tôi đã "cố định" (đọc lỗi nhỏ) vấn đề bằng cách bắt buộc sự kiện đã thay đổi thuộc tính cho thuộc tính 'SelectedValue' bị ràng buộc. Điều này dường như làm cho Combobox kiểm tra lại danh sách nội bộ của nó cho một mục khớp với trên SelectedValuePath đã định nghĩa.

Hộp kết hợp WPF phải 'biết' nó có một tập hợp giá trị SelectedValuePath, do đó tôi không nghĩ rằng nó quá xa của một bước nhảy vọt để giả định nó sẽ điều chỉnh mục phù hợp với logic của nó. Tuy nhiên điều này là đi ra ngoài phạm vi SO là dành cho. Tôi nhận ra tôi có thể sẽ chỉ chấp nhận điều này chỉ là cách WPF hoạt động, nhưng sau khi chiến đấu với combobox dữ liệu ràng buộc trong WinForms trong một vài năm, tôi hy vọng tôi sẽ không phải với WPF :) - Mặc dù nói rằng WPF Comboboxes là tốt hơn nhiều so với WinForm.

+0

ValuePath không quan trọng nếu đó là một đối tượng khác ... Bạn không thể mong đợi ràng buộc giữ vì nó ràng buộc với các đặc tính cụ thể (đối tượng). Khi bạn loại bỏ chúng, ràng buộc bị mất ... – UIlrvnd

+0

Phương thức xử lý của đối tượng được trả về bởi DelayNotificatons() làm tăng sự kiện CollectionChange với cờ ListReset. Tôi vẫn sẽ giả định combobox sẽ xem xét thông qua danh sách mới của nó cho một giá trị số nguyên nó có thể phù hợp trên ... Nếu điều này không phải là những gì xảy ra, lựa chọn của tôi là gì? – Marlon

+0

Trong ví dụ mã của bạn, bạn sử dụng cùng một trường hợp, vì điều duy nhất bạn thao tác là các bộ sưu tập. nó sẽ không xem xét vì các số nguyên là một ví dụ khác nhau mặc dù nó ** có ** cùng một giá trị ... Hy vọng nó làm cho sence lol ... – UIlrvnd

Trả lời

4

Tuyên bố này là sai

tôi có thể chấp nhận điều này nếu tôi đã không sử dụng các SelectedValuePath ràng buộc, nhưng vì tôi

Bạn đang không ràng buộc để SelectedValuePath.
Bạn đang ràng buộc với một bộ sưu tập các đối tượng.
SelectedValuePath chỉ dành cho báo cáo không có gì để làm với việc so sánh các đối tượng cho sự bình đẳng. DisplayMemberPath chỉ dành cho báo cáo không có gì để làm với việc so sánh các đối tượng cho sự bình đẳng.

Bạn nhầm lẫn SelectValuePath với SelectedItem.
ComboBox không sử dụng SelectedValuePath để xác định xem hai đối tượng có bằng nhau không.

Từ các tài liệu của SelectedValuePath:

Gets hoặc đặt con đường đó được sử dụng để có được những SelectedValue từ SelectedItem.

Trong mẫu gây bối rối cho bạn biết bạn đang tải các đối tượng cùng trở lại trong.

Tôi sẽ giả SelectedValuePath là một tài sản ID tên

Nếu bạn rõ ràng và tạo một đối tượng với một ID của 6 nó không bằng đối tượng đã xóa có ID là 6.

Hãy thử điều này. Tạo hai đối tượng (o1 và o2) với một ID là 6 và so sánh o1.Equals (o2).

Nếu bạn muốn hai đối tượng có ID là 6 bằng nhau thì bạn cần ghi đè GetHashCode và Equals. Trong Equals trả về true nếu cả hai đều có ID là 6. Và bạn có thể sử dụng ID làm GetHashCode.

Chuỗi là loại tham chiếu sẽ đánh lừa bạn.
chuỗi s1 = "mèo";
chuỗi s2 = "mèo";
s1.Equals (s2) sẽ trả về true vì String Equals được ghi đè để so sánh giá trị.

+0

Tôi thực sự hiểu điều đó, nhưng tôi ' m không ràng buộc với SelectedItem, tôi ràng buộc với SelectedValue. Vì vậy, tôi sẽ không mong đợi ComboBox để so sánh bình đẳng trên SelectedItem.Mặc dù tôi đoán nó có thể không thực sự xác định những gì tài sản ai đó đã bị ràng buộc và điều chỉnh logic nội bộ của nó để bộ. – Marlon

+0

Như được bao gồm trong câu trả lời của tôi và bình luận của Stefen không có bạn KHÔNG ràng buộc với SelectedValue. Bạn đang ràng buộc với một bộ sưu tập các đối tượng. DisplayMemberPath và SelectedValuePath chỉ dành cho báo cáo. Đây là câu trả lời. Tại sao bạn từ chối nó hơn là áp dụng nó? – Paparazzi

+0

Tôi không từ chối - tôi chỉ đơn thuần giải thích những gì tôi đang làm. Tôi không nghĩ rằng logic của tôi là vô căn cứ. Xem chỉnh sửa của tôi cho câu hỏi. Tôi sẽ cho nó một vài ngày nhưng tôi có lẽ sẽ chấp nhận câu trả lời của bạn. – Marlon

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