using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using Telerik.WinControls; using Telerik.WinControls.UI; using CustomComponents; namespace CustomComponents.GridView { // 1. Custom Cell Element public class AdvancedComboGridCellElement : GridDataCellElement { private AdvancedRadMultiColumnComboPlus _comboBox; private bool _isEditing; public AdvancedComboGridCellElement(GridViewColumn column, GridRowElement row) : base(column, row) { } protected override void CreateChildElements() { base.CreateChildElements(); // Wrap the AdvancedRadMultiColumnComboPlus in a RadHostItem to make it compatible with Telerik.RadElement var comboBoxHost = new RadHostItem(new AdvancedRadMultiColumnComboPlus()); _comboBox = (AdvancedRadMultiColumnComboPlus)comboBoxHost.HostedControl; this.Children.Add(comboBoxHost); } public override bool IsCompatible(GridViewColumn data, object context) { return data is AdvancedComboGridViewColumn && context is GridDataRowElement; } protected override void SetContentCore(object value) { if (_comboBox != null) { var column = this.ColumnInfo as AdvancedComboGridViewColumn; if (column != null) { // Configure ComboBox from column settings ConfigureComboBox(column); // Set selected value _comboBox.SelectedValue = value; // Display text this.Text = GetDisplayText(value, column); } } } private void ConfigureComboBox(AdvancedComboGridViewColumn column) { if (_comboBox.DataSource != column.DataSource) { _comboBox.DataSource = column.DataSource; _comboBox.DisplayMember = column.DisplayMember; _comboBox.ValueMember = column.ValueMember; // Apply column configurations _comboBox.ColumnsConfig.Clear(); _comboBox.ColumnsConfig.AddRange(column.ColumnsConfig); _comboBox.ApplyColumnConfigurations(); // Apply styling _comboBox.ItemFont = column.ItemFont; _comboBox.ItemForeColor = column.ItemForeColor; _comboBox.ItemBackColor = column.ItemBackColor; _comboBox.ItemRowHeight = column.ItemRowHeight; _comboBox.DropDownHeight = column.DropDownHeight; } } private string GetDisplayText(object value, AdvancedComboGridViewColumn column) { if (value == null || column.DataSource == null) return string.Empty; try { if (column.DataSource is System.Collections.IEnumerable enumerable) { foreach (var item in enumerable) { var itemValue = item.GetType().GetProperty(column.ValueMember)?.GetValue(item); if (Equals(itemValue, value)) { var displayValue = item.GetType().GetProperty(column.DisplayMember)?.GetValue(item); return displayValue?.ToString() ?? string.Empty; } } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"GetDisplayText failed: {ex.Message}"); } return value?.ToString() ?? string.Empty; } public override void BeginEdit() { if (!_isEditing) { _isEditing = true; _comboBox.Visible = true; _comboBox.BringToFront(); _comboBox.Focus(); _comboBox.ShowDropDown(); } } public override bool EndEdit() { if (_isEditing) { _isEditing = false; _comboBox.Visible = false; _comboBox.CloseDropDown(); // Update cell value var newValue = _comboBox.SelectedValue; if (!Equals(this.Value, newValue)) { this.Value = newValue; return true; } } return false; } private void ComboBox_SelectedValueChanged(object sender, EventArgs e) { if (_isEditing) { // Update display text var column = this.ColumnInfo as AdvancedComboGridViewColumn; if (column != null) { this.Text = GetDisplayText(_comboBox.SelectedValue, column); } } } protected override void DisposeManagedResources() { if (_comboBox != null) { _comboBox.SelectedValueChanged -= ComboBox_SelectedValueChanged; _comboBox.Dispose(); _comboBox = null; } base.DisposeManagedResources(); } protected override SizeF ArrangeOverride(SizeF finalSize) { var result = base.ArrangeOverride(finalSize); if (_comboBox != null && _isEditing) { _comboBox.Size = new Size((int)finalSize.Width, (int)finalSize.Height); _comboBox.Location = new Point(0, 0); } return result; } } // 2. Custom Column public class AdvancedComboGridViewColumn : GridViewDataColumn { private object _dataSource; private string _displayMember = string.Empty; private string _valueMember = string.Empty; private System.Collections.Generic.List _columnsConfig; // Styling properties private Font _itemFont = new Font("Tahoma", 9); private Color _itemForeColor = SystemColors.ControlText; private Color _itemBackColor = SystemColors.Window; private int _itemRowHeight = 32; private int _dropDownHeight = 300; public AdvancedComboGridViewColumn() : base() { _columnsConfig = new System.Collections.Generic.List(); } public AdvancedComboGridViewColumn(string fieldName) : base(fieldName) { _columnsConfig = new System.Collections.Generic.List(); } // Data Properties [Category("Data")] [Description("Data source for the dropdown")] public object DataSource { get => _dataSource; set => _dataSource = value; } [Category("Data")] [Description("Property to display in the dropdown")] public string DisplayMember { get => _displayMember; set => _displayMember = value ?? string.Empty; } [Category("Data")] [Description("Property to use as value")] public string ValueMember { get => _valueMember; set => _valueMember = value ?? string.Empty; } [Category("Data")] [Description("Column configuration for the dropdown")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public System.Collections.Generic.List ColumnsConfig { get => _columnsConfig; set => _columnsConfig = value ?? new System.Collections.Generic.List(); } // Appearance Properties [Category("Appearance")] [Description("Font for dropdown items")] public Font ItemFont { get => _itemFont; set => _itemFont = value ?? new Font("Tahoma", 9); } [Category("Appearance")] [Description("Text color for dropdown items")] public Color ItemForeColor { get => _itemForeColor; set => _itemForeColor = value; } [Category("Appearance")] [Description("Background color for dropdown items")] public Color ItemBackColor { get => _itemBackColor; set => _itemBackColor = value; } [Category("Appearance")] [Description("Height of dropdown rows")] public int ItemRowHeight { get => _itemRowHeight; set => _itemRowHeight = Math.Max(16, value); } [Category("Appearance")] [Description("Height of the dropdown")] public int DropDownHeight { get => _dropDownHeight; set => _dropDownHeight = Math.Max(100, value); } public override Type GetCellType(GridViewRowInfo row) { if (row is GridViewDataRowInfo) return typeof(AdvancedComboGridCellElement); return base.GetCellType(row); } } // 3. Custom Editor for better integration public class AdvancedComboGridViewEditor : BaseGridEditor { private AdvancedRadMultiColumnComboPlus _comboBox; public override object Value { get => _comboBox?.SelectedValue; set { if (_comboBox != null) { _comboBox.SelectedValue = value; } } } public override void BeginEdit() { base.BeginEdit(); _comboBox?.ShowDropDown(); } public override bool EndEdit() { _comboBox?.CloseDropDown(); return base.EndEdit(); } // Fix for CS1061: Replace the problematic line with a valid implementation. protected override RadElement CreateEditorElement() { _comboBox = new AdvancedRadMultiColumnComboPlus(); _comboBox.SelectedValueChanged += ComboBox_ValueChanged; // Since 'AdvancedRadMultiColumnComboPlus' does not have 'GetChildAt', // directly return the RadHostItem wrapping the combo box. return new RadHostItem(_comboBox); } private void ComboBox_ValueChanged(object sender, EventArgs e) { OnValueChanged(); } public override void Initialize(object owner, object value) { base.Initialize(owner, value); if (owner is AdvancedComboGridViewColumn column) { _comboBox.DataSource = column.DataSource; _comboBox.DisplayMember = column.DisplayMember; _comboBox.ValueMember = column.ValueMember; _comboBox.ColumnsConfig.Clear(); _comboBox.ColumnsConfig.AddRange(column.ColumnsConfig); _comboBox.ApplyColumnConfigurations(); } } } }