This question is locked. New answers and comments are not allowed.
Greetings,
I have cooked up a simple example that hopefully illustrates what I am trying to accomplish. Consider the following:
I have a Person business object that is defined as such. I've eliminated the INotifyPropertyChanged implementation to keep things clear. Note that Person.PetType is a nullable enum.
Simply put, I would like to edit a list of Person business objects in a RadGridView with a GridViewComboBoxColumn in the PetType column that will allow the user to select between Dog, Cat, Cow, and None (null).
I construct my RadGridView the following way:
The method for GetPetsList() is defined as follows:
ValueListItem is a simple class that i thought would help facilitate the picklist creation. It has two members Id (int?) and Code (string).
I believe I have implemented the ValueConverter correctly. I was hoping it would convert the PetType enum value (or null) from the business object to an integer (or null) for databinding. Similarly, I was hoping it would convert integers (or null) from databinding to a PetType enum value (or null) for the business object. Make sense?
For the sake of brevity, I'm not providing the GetPersons() method. It simply returns an IEnumerable<Person>.
Everything works great until I add in the 'null' item in the GetPetsList() method. When I add the null item, my Silverlight application crashes. I managed to get a stack trace once...
I am using the Q2/2009 controls for Silverlight 2. Any thoughts on what I could be doing wrong? Any ideas on a work around if this is not supported behvior? We really need this type of functionality for our application.
Thanks!
I have cooked up a simple example that hopefully illustrates what I am trying to accomplish. Consider the following:
I have a Person business object that is defined as such. I've eliminated the INotifyPropertyChanged implementation to keep things clear. Note that Person.PetType is a nullable enum.
| public class Person |
| { |
| public Person() { } |
| public string Name { get; set; } |
| public int Age { get; set; } |
| public PetType? PetType { get; set; } |
| } |
| public enum PetType |
| { |
| Dog = 1, |
| Cat = 2, |
| Cow = 3 |
| } |
Simply put, I would like to edit a list of Person business objects in a RadGridView with a GridViewComboBoxColumn in the PetType column that will allow the user to select between Dog, Cat, Cow, and None (null).
I construct my RadGridView the following way:
| this.RadGridView.Columns.Add(new GridViewDataColumn() { UniqueName = "Name", DataType = typeof(string) }); |
| this.RadGridView.Columns.Add(new GridViewDataColumn() { UniqueName = "Age", DataType = typeof(int) }); |
| GridViewComboBoxColumn comboBoxColumn = new GridViewComboBoxColumn(); |
| comboBoxColumn.UniqueName = "PetType"; |
| comboBoxColumn.DataType = typeof(PetType?); |
| comboBoxColumn.DataMemberBinding = new Binding() |
| { |
| Mode = BindingMode.TwoWay, |
| Path = new PropertyPath("PetType"), |
| Converter = new ValueConverter() |
| }; |
| comboBoxColumn.SelectedValueMemberPath = "Id"; |
| comboBoxColumn.DisplayMemberPath = "Code"; |
| comboBoxColumn.ItemsSource = GetPetsList(); |
| this.RadGridView.Columns.Add(comboBoxColumn); |
| this.RadGridView.ItemsSource = GetPersons(); |
The method for GetPetsList() is defined as follows:
| private IEnumerable<ValueListItem> GetPetsList() |
| { |
| List<ValueListItem> pets = new List<ValueListItem>(); |
| pets.Add(new ValueListItem() { Id = null, Code = "(None)" }); |
| pets.Add(new ValueListItem() { Id = 1, Code = "(Dog) Dog" }); |
| pets.Add(new ValueListItem() { Id = 2, Code = "(Cat) Cat" }); |
| pets.Add(new ValueListItem() { Id = 3, Code = "(Cow) Cow" }); |
| return pets.AsEnumerable(); |
| } |
ValueListItem is a simple class that i thought would help facilitate the picklist creation. It has two members Id (int?) and Code (string).
I believe I have implemented the ValueConverter correctly. I was hoping it would convert the PetType enum value (or null) from the business object to an integer (or null) for databinding. Similarly, I was hoping it would convert integers (or null) from databinding to a PetType enum value (or null) for the business object. Make sense?
| public class ValueConverter : IValueConverter |
| { |
| public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
| { |
| if (value != null) |
| { |
| return (int)value; |
| } |
| return null; |
| } |
| public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
| { |
| if (value != null) |
| { |
| int i; |
| if (Int32.TryParse(value.ToString(), out i)) |
| { |
| return Enum.ToObject(typeof(PetType), i); |
| } |
| } |
| return null; |
| } |
| } |
For the sake of brevity, I'm not providing the GetPersons() method. It simply returns an IEnumerable<Person>.
Everything works great until I add in the 'null' item in the GetPetsList() method. When I add the null item, my Silverlight application crashes. I managed to get a stack trace once...
| at Telerik.Windows.Controls.LookupValueConverter.GetValueToDisplay(Object value, IEnumerable items, String pathToDisplayMember, String pathToValueMember) |
| at Telerik.Windows.Controls.LookupValueConverter.Convert(Object value, Type targetType, Object parameter, CultureInfo culture) |
| at Telerik.Windows.Controls.GridViewComboBoxColumn.ConvertValueToContent(Object value) |
| at Telerik.Windows.Controls.GridView.GridViewCellBase.ConvertValueToContent(Object value) |
| at Telerik.Windows.Controls.GridView.GridViewCell.OnValueChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) |
| at Telerik.Windows.PropertyMetadata.<>c__DisplayClass1.<Create>b__0(DependencyObject d, DependencyPropertyChangedEventArgs e) |
| at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value, Boolean allowReadOnlySet, Boolean isSetByStyle, Boolean isSetByBuiltInStyle) |
| at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value) |
| at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value) |
| at Telerik.Windows.Controls.GridView.GridViewCell.set_Value(Object value) |
| at Telerik.Windows.Controls.GridView.EditContext.CommitValidContent(GridViewCell cell) |
| at Telerik.Windows.Controls.GridView.EditContext.CommitCellEdit(GridViewCell cell) |
| at Telerik.Windows.Controls.GridView.EditContext.TryCommitPreviouslyEditedCell(GridViewCell cell) |
| at Telerik.Windows.Controls.GridView.EditContext.TryCommitPreviouslyEditedData(GridViewCell cell) |
| at Telerik.Windows.Controls.GridView.EditContext.TryMakeCellCurrent(GridViewCell cell) |
| at Telerik.Windows.Controls.GridView.GridViewCell.IsCurrentChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) |
| at Telerik.Windows.PropertyMetadata.<>c__DisplayClass1.<Create>b__0(DependencyObject d, DependencyPropertyChangedEventArgs e) |
| at System.Windows.DependencyObject.RaisePropertyChangeNotifications(DependencyProperty dp, Object newValue, Object oldValue) |
| at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value, Boolean allowReadOnlySet, Boolean isSetByStyle, Boolean isSetByBuiltInStyle) |
| at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value) |
| at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value) |
| at Telerik.Windows.Controls.GridView.GridViewCell.set_IsCurrent(Boolean value) |
| at Telerik.Windows.Controls.GridView.GridViewCell.OnGotFocus(RoutedEventArgs e) |
| at System.Windows.Controls.Control.OnGotFocus(Control ctrl, EventArgs e) |
| at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName) |
I am using the Q2/2009 controls for Silverlight 2. Any thoughts on what I could be doing wrong? Any ideas on a work around if this is not supported behvior? We really need this type of functionality for our application.
Thanks!