This is a migrated thread and some comments may be shown as answers.

GridViewComboBoxColumn DBNull issue

3 Answers 116 Views
GridView
This is a migrated thread and some comments may be shown as answers.
David A.
Top achievements
Rank 1
David A. asked on 09 Apr 2011, 11:15 PM
Hi,

I have a ComboBoxColumn that is bound to a datatable.  One of the options in the datatable is "None" with a value of DBNull.  I have the DisplayMember and ValueMember set and everything works just fine, except when I choose "None" in the list and move off the row. The column with the ComboBox is empty instead of "None".  Any other value displays the lookup text just fine.

Any ideas?

3 Answers, 1 is accepted

Sort by
0
Accepted
Svett
Telerik team
answered on 13 Apr 2011, 04:49 PM
Hello David A.,

Thank you for the detailed issue description. It helped me to reproduce the issue. I confirm that it appears in our latest release and I logged it in our bug tracking system. The issue will be addressed in one of our upcoming releases.

You can work around the issue by using the following work around:

public partial class GridForm : Form
{
    public GridForm()
    {
        InitializeComponent();
 
        this.radGridView1.CellEditorInitialized += new GridViewCellEventHandler(radGridView1_CellEditorInitialized);
    }
 
    private void radGridView1_CellEditorInitialized(object sender, GridViewCellEventArgs e)
    {
        RadDropDownListEditor editor = e.ActiveEditor as RadDropDownListEditor;
        if (editor != null && this.radGridView1.CurrentColumn.Name == "Status" && editor.Value == null)
        {
            RadDropDownListEditorElement element = editor.EditorElement as RadDropDownListEditorElement;
            element.SelectedIndex = 0;
        }
    }
 
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
 
        this.radGridView1.DataSource = GetDummyEmployeesDataSource();
 
        DataTable statusSource = new DataTable("table");
        statusSource.Columns.Add("Name", typeof(string));
        statusSource.Columns.Add("Value", typeof(int));
 
        statusSource.Rows.Add("None", DBNull.Value);
        statusSource.Rows.Add("Pending", 1);
        statusSource.Rows.Add("Approved", 2);
 
        MyGridViewComboBoxColumn comboColumn = new MyGridViewComboBoxColumn("Status", "Status");
        comboColumn.ValueMember = "Value";
        comboColumn.DisplayMember = "Name";
        comboColumn.DataSource = statusSource;
 
        this.radGridView1.Columns.Add(comboColumn);
    }
 
    public class MyGridViewComboBoxColumn : GridViewComboBoxColumn
    {
        private static MethodInfo ensureDescriptorsMethod;
        private static FieldInfo currencyManagerField;
        private static FieldInfo valueDescriptorField;
        private static FieldInfo displayDescriptorField;
 
        static MyGridViewComboBoxColumn()
        {
            Type cbType = typeof(GridViewComboBoxColumn);
 
            ensureDescriptorsMethod = cbType.GetMethod("EnsureDescriptors", BindingFlags.InvokeMethod |
                                                                      BindingFlags.Instance |
                                                                      BindingFlags.NonPublic);
 
            currencyManagerField = cbType.GetField("currencyManager", BindingFlags.NonPublic | BindingFlags.Instance);
            valueDescriptorField = cbType.GetField("valueDescriptor", BindingFlags.NonPublic | BindingFlags.Instance);
            displayDescriptorField = cbType.GetField("displayDescriptor", BindingFlags.NonPublic | BindingFlags.Instance);
        }
 
        public MyGridViewComboBoxColumn(string fieldName)
            : base(fieldName)
        {
 
        }
 
        public MyGridViewComboBoxColumn()
        {
 
        }
 
        public MyGridViewComboBoxColumn(string uniqueName, string fieldName)
            : base(uniqueName, fieldName)
        {
 
        }
 
        public override object GetLookupValue(object cellValue)
        {
            if ((bool)ensureDescriptorsMethod.Invoke(this, null))
            {
                CurrencyManager currencyManager = currencyManagerField.GetValue(this) as CurrencyManager;
                PropertyDescriptor valueDescriptor = valueDescriptorField.GetValue(this) as PropertyDescriptor;
                PropertyDescriptor displayDescriptor = displayDescriptorField.GetValue(this) as PropertyDescriptor;
 
                bool isNullValue = this.IsNullValue(cellValue);
 
                for (int i = 0; i < currencyManager.List.Count; i++)
                {
                    object val = valueDescriptor.GetValue(currencyManager.List[i]);
 
                    if ((isNullValue && this.IsNullValue(val)) || Object.Equals(cellValue, val))
                    {
                        return displayDescriptor.GetValue(currencyManager.List[i]);
                    }
                }
            }
 
            return null;
        }
 
        private bool IsNullValue(object value)
        {
            return value == null || Convert.IsDBNull(value);
        }
    }
}

I updated your Telerik points accordingly. Should you have any further questions, do not hesitate to ask.

Kind regards,
Svett
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Exclamation
Top achievements
Rank 1
answered on 08 Jun 2012, 07:24 AM
Hi , Svett.
Can you tell me how the EnsureDescriptors Method work with source.
I customer your GetLookupVale but (bool)ensureDescriptorsMethod.Invoke(this, null) alway false.I dont know why.
I have set Datasouce . DisplayMember, ValueMember for this colum.
Idea can i remove (bool)ensureDescriptorsMethod.Invoke(this, null)  in code of method.
Thanks your reply.
0
Julian Benkov
Telerik team
answered on 13 Jun 2012, 08:28 AM
Hello Thanh,

You can remove EnsureDescriptors reflection call in your application and add a null reference check of the CurrencyManager, Value and display descriptors. Here is a modified example:
public override object GetLookupValue(object cellValue)
{
    CurrencyManager currencyManager = currencyManagerField.GetValue(this) as CurrencyManager;
    PropertyDescriptor valueDescriptor = valueDescriptorField.GetValue(this) as PropertyDescriptor;
    PropertyDescriptor displayDescriptor = displayDescriptorField.GetValue(this) as PropertyDescriptor;
 
    if(currencyManager != null && valueDescriptor != null && displayDescriptor != null)
    {
        bool isNullValue = this.IsNullValue(cellValue);
 
        for (int i = 0; i < currencyManager.List.Count; i++)
        {
            object val = valueDescriptor.GetValue(currencyManager.List[i]);
 
            if ((isNullValue && this.IsNullValue(val)) || Object.Equals(cellValue, val))
            {
                return displayDescriptor.GetValue(currencyManager.List[i]);
            }
        }
    }
     
    return null;
}

I hope this helps.

Regards,
Julian Benkov
the Telerik team
RadControls for WinForms Q1'12 release is now live! Check out what's new or download a free trial >>
Tags
GridView
Asked by
David A.
Top achievements
Rank 1
Answers by
Svett
Telerik team
Exclamation
Top achievements
Rank 1
Julian Benkov
Telerik team
Share this question
or