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à AllowedValues
và boolean
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 INotifyPropertyChanged
và INotifyPropertyChanging
.
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 và sử dụng ActualValue
tài sản để chọn đúng Value
từ AllowedValues
BindableDictionary
để đ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).