DataGridViewComboBoxColumn: cell display when not edited?

Oct 22, 2008 at 4:56 PM
Hi, All!

I've been trying to use a ComboBox column.  Everything works fine when I edit the cell, it has the right starting value, and changes are propagating back to the main DataGrid item.  The data grid item is a Linq data entity, as are the ComboBox items.  The following code sets up the EditingElementStyle within an AutoGeneratingColumn event, and works fine.

                DataGridComboBoxColumn c = new DataGridComboBoxColumn();
                c.DataFieldBinding = new Binding(e.PropertyName);
                c.ItemsSource = (System.Collections.IEnumerable) myItemsSource;
                c.DataFieldTarget = ComboBoxDataFieldTarget.SelectedItem;
                c.Header = e.Column.Header;
                Style sbox = new Style(typeof(ComboBox));
                Setter s = new Setter(ComboBox.DisplayMemberPathProperty, "Name");
                sbox.Setters.Add(s);
                c.EditingElementStyle = sbox;
                e.Column = c;

My problem is I can't seem to get anything to display in non-editing mode.  I try to set the ElementStyle, but nothing happens.

                Style stytxt = new Style(typeof(TextBlock));
                Binding b=new Binding(e.PropertyName);
                b.ElementName="Name";
                b.FallbackValue = "Fallback";
                Setter settxt = new Setter(TextBlock.TextProperty, b);
                stytxt.Setters.Add(settxt);
                c.ElementStyle = stytxt;

This has no effect, and nothing displays in the cell when it's not being edited.  What should I do here? I have no problem creating a converter from the ComboBox data entity to string, but where would I slot that in?  Any help would be appreciated.

Alonzo

Coordinator
Oct 30, 2008 at 2:14 PM
Have you tried your scenario out with the new DataGridComboBoxColumn?  There has been an API makeover for that column.  Try it out and if you are running into the same issues just let us know.
Oct 30, 2008 at 5:47 PM
Hi, thanks for getting back to me.

I've managed to solve this by implementing a full converter as below.  This works against the pre-release WPFtoolkit.  If the DataFieldBinding property hasn't changed too much, then maybe it'll keep working against the release WPFtoolkit, but I haven't had a chance to try it yet.  The limitation of the below is that it displays only 1 column, the "Name" column.  I'd actually like it to display two columns concatenated together like this: "Project/Name".  There's no problem getting the converter to do this, but as I'm relying on the ComboBox DisplayMemberPath propery as well, I'm not sure what to do.

Alonzo

                //this code goes in the AutoGeneratingColumn event
                //create the combobox column
                DataGridComboBoxColumn c = new DataGridComboBoxColumn();
                //the DataFieldBinding must convert DataEntity to string
                Binding b = new Binding(e.PropertyName);
                //propinfo can get the name from the DataEntity, create a custom converter for this class
                PropertyInfo propinfo = e.PropertyType.GetProperty("Name");
                IValueConverter con = new DataEntityConverter(propinfo);
                b.Converter = con;
                //finish setting up the column
                c.DataFieldBinding = b;
                c.ItemsSource = (System.Collections.IEnumerable) mySource;
                c.DataFieldTarget = ComboBoxDataFieldTarget.SelectedItem;
                c.Header = e.Column.Header;
                //combobox display member is Name, use style to set this
                Style sbox = new Style(typeof(ComboBox));
                Setter s = new Setter(ComboBox.DisplayMemberPathProperty, "Name");
                sbox.Setters.Add(s);
                c.EditingElementStyle = sbox;
                //replace autogenerated column
                e.Column = c;


        //need to have this as well
        public class DataEntityConverter : IValueConverter
        {
            PropertyInfo propinfo;

            public DataEntityConverter(PropertyInfo propinfo)
            { this.propinfo = propinfo; }

            #region IValueConverter Members

            public object Convert(object value, Type targetType, object parameter,
                System.Globalization.CultureInfo culture)
            {
                if (targetType == typeof(string))
                {
                    if (value == null) return string.Empty;
                    return propinfo.GetValue(value, null);
                }
                else if (targetType == typeof(object))
                    return value;
                else
                    throw new InvalidOperationException("The target must be a string or object");
            }

            public object ConvertBack(object value, Type targetType, object parameter,
                System.Globalization.CultureInfo culture)
            {
                return value;
            }

            #endregion
        }