2013-11-27 13 views
5

Tôi đang tạo một DataGrid theo lập trình và phải hỗ trợ ComboBoxColumns.Ràng buộc một DataGridComboBoxColumn vào ItemsSource của DataGrid trong C#

Sau khi tạo DataGrid, tôi đặt số ItemSource thành bộ sưu tập của một loại hình BindableList<BindableDictionary>. BindableDictionary là loại tùy chỉnh. Mỗi BindableDictionary đại diện cho một bộ. Khóa của nó luôn là tên của một cột và giá trị của nó là một lớp tùy chỉnh có chứa thuộc tính chung được gọi là ActualValue, Dictionary<T, string> được gọi là AllowedValuesboolean xác định nếu AllowedValues sẽ được sử dụng để tạo một cột ComboBoxColumn hoặc cột 'bình thường'. Ngoài ra, lớp học triển khai INotifyPropertyChangedINotifyPropertyChanging.

Công cụ đó hoạt động, ngoài ComboBoxColumn, duh. Vấn đề của tôi với ComboBoxColumn là tôi không biết làm thế nào để có được nó để sử dụng đối tượng AllowedValues để điền vào nó ItemList sử dụng ActualValue tài sản để chọn đúng Value từ AllowedValuesBindableDictionary để điền vào textarea.

Như một ví dụ, đây là cách tôi gắn một cột textbased:

table.Columns.Add(new DataGridTextColumn() { Header = column.GUIName, DisplayIndex = column.Position, Binding = new Binding(column.Name + ".ActualValue") { UpdateSourceTrigger = UpdateSourceTrigger.Default, Mode = BindingMode.TwoWay, NotifyOnTargetUpdated = true, NotifyOnSourceUpdated = true, UpdateSourceExceptionFilter = new UpdateSourceExceptionFilterCallback(BindingExceptionHandler) } }); 

Và có, mà làm việc.

Tôi cố gắng để thiết lập các ItemsSource tài sản của DataGridComboBoxColumn-column.AllowedValues và thiết lập DisplayPath-"Value" mà ít nhất hiển thị các nội dung chính xác, nhưng tôi đã không có đầu mối làm thế nào để liên kết với ActualValue tài sản đó được chứa trong DataGrid 's ItemsSource. Điều đó cũng có nghĩa là tất cả các ô bên trong một cột có cùng giá trị có thể lựa chọn, có thể dẫn đến các vấn đề trong tương lai.

Và nếu tôi cố gắng ràng buộc mọi thứ như tôi đã làm trong DataGridTextColumn, thì không có gì được hiển thị cả. Cũng không có mục nào để chọn.

Thật tuyệt vời nếu ai đó có quá nhiều gợi ý về những gì tôi có thể thử.

chỉnh sửa

Chỉ cần thấy điều này: https://stackoverflow.com/a/2197004/937093, tôi đã cố gắng đó, nhưng sau đó tôi nhận được thông báo sau trong cửa sổ đầu ra của tôi:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=AllowedValues; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=33493530); target property is 'ItemsSource' (type 'IEnumerable')

Mã của tôi trông như thế này:

col = new DataGridComboBoxColumn() { Header = column.GUIName, SelectedValueBinding = new Binding(column.Name + ".ActualValue"), SelectedValuePath = "ActualValue" }; 
table.Columns.Add(col); 
BindingOperations.SetBinding(col, DataGridComboBoxColumn.ItemsSourceProperty, new Binding("AllowedValues")); 

chỉnh sửa 2 được, tìm thấy trang web: http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/

Tôi đã cố gắng áp dụng các công cụ ràng buộc proxy (mặc dù tôi không hiểu cách Cột không phải là một phần của cây trực quan của DataGrid ... ở đâu khác?) nó sẽ không hoạt động.Mã của tôi:

BindingProxy proxy = new BindingProxy() { Data = table.ItemsSource }; 
table.Resources.Add("proxy", proxy }); 
col = new DataGridComboBoxColumn() { Header = column.GUIName, SelectedValueBinding = new Binding("Data." + column.Name + ".ActualValue") { Source = proxy }, DisplayMemberPath = "Value", SelectedValuePath = "Key" }; 
table.Columns.Add(col); 
BindingOperations.SetBinding(col, DataGridComboBoxColumn.ItemsSourceProperty, new Binding("Data." + column.Name + ".AllowedValues") }); 

Output trong cửa sổ đầu ra:

System.Windows.Data Error: 40 : BindingExpression path error: 'MyColumn' property not found on 'object' ''BindingList`1' (HashCode=55207835)'. BindingExpression:Path=Data.MyColumn.ActualValue; DataItem='BindingProxy' (HashCode=45660050); target element is 'TextBlockComboBox' (Name=''); target property is 'SelectedValue' (type 'Object')

Tôi hiểu vấn đề (nó đang cố gắng để tìm ra đối tượng 'MyColumn' trong BindingList) nhưng tôi không hiểu tại sao điều đó đang xảy ra (nó sẽ giải quyết cho BindingList [iterator] ["MyColumn"], vì BindingList chứa BindableDictionary và đó chính xác là những gì xảy ra cho các cột 'bình thường' của tôi).

Trả lời

0

Tôi đã làm một việc tương tự. Tôi đã sử dụng Winforms, vì vậy giải pháp của tôi có thể không hoạt động cho bạn. Tuy nhiên tôi muốn đề nghị sử dụng một cái gì đó tương tự như thế này.

http://tech.pro/tutorial/776/csharp-tutorial-binding-a-datagridview-to-a-collection

Cùng với điều này.

http://www.codeproject.com/Articles/31418/Implementing-a-Sortable-BindingList-Very-Very-Quic

Như tôi đã có mọi thứ làm việc, sau đó tìm thấy tôi không thể sắp xếp datagridview của tôi.

Tôi không có mã nguồn của tôi tiện dụng, nhưng ý tưởng chung là tôi sẽ tạo các hộp combobox và hộp văn bản của mình bằng tay, sau đó liên kết danh sách của tôi với nó.

Sau khi tôi chạy một hàm sẽ lặp qua từng hàng và dựa trên chỉ mục (trong trường hợp của tôi hộp kết hợp của tôi là 3 cột cuối cùng), tôi sẽ thêm giá trị cho combobox bằng tay trước, sau đó sau chúng được thêm vào, tôi sẽ kiểm tra giá trị của combobox và đặt nó vào đó.

Tôi cũng đưa chức năng này vào sự kiện lỗi dữ liệu, khi tôi thêm cột mới. Ngoài ra nó sẽ ngẫu nhiên sụp đổ nếu tôi đã thêm một hàng mới, nếu tôi đã có bộ autosize. Tôi đã phải thiết lập những mặc định, làm chỉnh sửa của tôi, sau đó đặt lại nó.

Tôi muốn có mã để cung cấp, nhưng nó có thể khiến bạn trên đường. Nếu không phải khi tôi đi làm vào ngày mai tôi sẽ đăng một số. Comboboxes là một nỗi đau lớn để làm việc với.

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