阅读了很多关于这个明显令人烦恼的问题的答案,包括这个似乎指明了方向的出色回复:Add handler to factory,经过几天尝试阅读各种不同的建议后,我仍然无法在我的设置中使用它在这个网站上。
因此,底层数据结构的公共成员是:
#region Public Members
public EMSBasicDevice Device { get => _Device; set => _Device = value; }
public BitmapImage DeviceIcon { get => _DeviceIcon; set => _DeviceIcon = value; }
public string DeviceIconPath { get => _DeviceIconPath; set => _DeviceIconPath = value; }
public int RowHeight { get => _RowHeight; set => _RowHeight = value; }
public Color RowColour { get => _RowColour; set => _RowColour = value; }
public string DataDescription { get => _DataDescription; set => _DataDescription = value; }
public string ZoneText { get => _Zone; set => _Zone = value; }
public string LocationText { get => _LocationText; set => _LocationText = value; }
public bool IsHeader { get => _IsHeader; set => _IsHeader = value; }
public InputOutput IOType { get => _IOType; set => _IOType = value; }
public CellControl ShowCombo { get => _ShowCombo; set => _ShowCombo = value; }
public int IOPoint { get => _IOPoint; set => _IOPoint = value; }
public int IOIndex { get => _IOIndex; set => _IOIndex = value; }
public int RowNumber { get => _RowNumber; set => _RowNumber = value; }
public Visibility SensorVis { get => _SensorVis; set => _SensorVis = value; }
public IEnumerable ItemsSource { get => _ItemsSource; set => _ItemsSource = value; }
public object SelectedItem { get => _SelectedItem; set => _SelectedItem = value; }
public SelectionChangedEventHandler OnChange;
#endregion
目标 UI 元素是 DataGrid。所有列都在代码中显式创建。这是第 4 列的代码,用于保存 ComboBox。为选项列表 (ItemsSource)、所选项目、控件是否显示(不是在网格的每一行上)和(尝试)传递对“更改处理程序”的引用提供绑定。工厂元素 ComboBoxes 没有用于更改处理程序的 DP。所以我的代码看起来像这样,遵循上面链接中给出的信息:
// Fourth Column: Sensor Settings
DataGridTemplateColumn SensorSettingCol = new DataGridTemplateColumn();
Binding SensorChoicesBind = new Binding("ItemsSource")
{
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
};
Binding SensorSettingBind = new Binding("SelectedItem")
{
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
NotifyOnSourceUpdated = true
};
Binding SensorVisibility = new Binding("SensorVis")
{
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};
Binding OnChangeBinding = new Binding("OnChange")
{
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};
FrameworkElementFactory cbInstance1 = new FrameworkElementFactory(typeof(ComboBox));
ImageTemplate = new DataTemplate();
SensorSettingCol.CellTemplate = ImageTemplate;
SensorSettingCol.Width = new DataGridLength(150);
SensorSettingCol.CanUserSort = false;
ImageTemplate.VisualTree = cbInstance1;
cbInstance1.SetBinding(ComboBox.ItemsSourceProperty, SensorChoicesBind);
cbInstance1.SetBinding(ComboBox.SelectedValueProperty, SensorSettingBind);
cbInstance1.SetBinding(ComboBox.VisibilityProperty, SensorVisibility);
cbInstance1.AddHandler(ComboBox.SelectionChangedEvent, new RoutedPropertyChangedEventHandler<object>(SelectionChanged));
TheDataGrid.Columns.Add(SensorSettingCol);
The handler looks like this:
public void SelectionChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
//do stuff with e.OriginalSource
}
Of course, this is only half the problem - the real issue is accessing the actual handler in the dataset
which should be called when the user selects a different choice in the ComboBox. Note that the
implementation is intended to be as generic as possible - the combo boxes on different rows access
different choices based upon the underlying dataset.
The error message is:
System.ArgumentException
HResult=0x80070057
Message=Handler type is not valid.
Source=PresentationFramework
StackTrace:
at System.Windows.FrameworkElementFactory.AddHandler(RoutedEvent routedEvent, Delegate handler, Boolean handledEventsToo)
at System.Windows.FrameworkElementFactory.AddHandler(RoutedEvent routedEvent, Delegate handler)
at EMS_Config_Tool.UIComponents.WPF.DeviceEditControl.SetupDeviceGrid(DataGrid TheDataGrid) in C:\Workspace\90504_SmartCellConfigTool\Trunk\EMS Config Tool\UIComponents\WPF\DeviceEditControl.xaml.cs:line 794
The question is: The handler type is wrong, so what should the type actually be?
And for a Gold Star, is there a MUCH BETTER way to link the SelectionChanged event
to the appropriate handler?