This question is locked. New answers and comments are not allowed.
I came across an annoying bug in the RadTreeListView this morning!
If I have a class hierarchy similiar to:
With Xaml similiar to:
Using this code, I get an exception when I try to edit Joe, Sam, George, or Frank:
However if I use the following code:
I don't get the exception.
Notice the only difference is I included both derived classes in the root collection in the working case, where as there was only a single derived class in the failing case.
The exception I am receiving is "Unable to cast object of type 'SilverlightApplication5.Client' to type 'SilverlightApplication5.Employee'."
The stack trace is:
One workaround I thought of was to included the second derived class for binding, then remove the second item right away, similar to:
However that doesn't appear to work...
A second more viable option might be a strategy pattern where there is only a single class in the grid, but this class delegates to the various derived classes. A "hack" but it should work.
Any thoughts?
In my actual use case there will only be one derived class in the grid's root, then a plethora of derived classes down the hierarchy of the grid...
Thanks
Jay
If I have a class hierarchy similiar to:
public abstract class Person { public string Name { get; set; } public decimal Sales { get; set; } public bool IsReadOnly { get; set; } public abstract string Type { get; } private readonly ObservableCollection<Person> _people = new ObservableCollection<Person>(); public ObservableCollection<Person> People { get { return _people; } } } public class Employee : Person { public Employee() { IsReadOnly = true; } public override string Type { get { return "Employee"; } } } public class Client : Person { public override string Type { get { return "Client"; } } } With Xaml similiar to:
<telerik:RadTreeListView Name="radTreeListView1" AutoGenerateColumns="false" > <telerik:RadTreeListView.ChildTableDefinitions> <telerik:TreeListViewTableDefinition ItemsSource="{Binding People}" /> </telerik:RadTreeListView.ChildTableDefinitions> <telerik:RadTreeListView.Columns> <telerik:GridViewDataColumn DataMemberBinding="{Binding Name}" Header="Name" IsReadOnlyBinding="{Binding IsReadOnly}" /> <telerik:GridViewDataColumn DataMemberBinding="{Binding Type}" Header="Type" IsReadOnlyBinding="{Binding IsReadOnly}" /> <telerik:GridViewDataColumn DataMemberBinding="{Binding Sales}" Header="Sales" IsReadOnlyBinding="{Binding IsReadOnly}" /> <telerik:GridViewDataColumn DataMemberBinding="{Binding IsReadOnly}" Header="IsReadOnly" IsReadOnlyBinding="{Binding IsReadOnly}" /> </telerik:RadTreeListView.Columns> </telerik:RadTreeListView>Using this code, I get an exception when I try to edit Joe, Sam, George, or Frank:
public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); var list = new ObservableCollection<Person>(); Employee sam = new Employee() { Name = "Alice" }; list.Add(sam); sam.People.Add(new Client() { Name = "Joe" }); sam.People.Add(new Client() { Name = "Sam" }); Employee john = new Employee() { Name = "John" }; john.People.Add(new Client() { Name = "George" }); john.People.Add(new Client() { Name = "Frank" }); list.Add(john); //list.Add(new Client() { Name = "Jay" }); radTreeListView1.ItemsSource = list; } } However if I use the following code:
public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); var list = new ObservableCollection<Person>(); Employee sam = new Employee() { Name = "Alice" }; list.Add(sam); sam.People.Add(new Client() { Name = "Joe" }); sam.People.Add(new Client() { Name = "Sam" }); Employee john = new Employee() { Name = "John" }; john.People.Add(new Client() { Name = "George" }); john.People.Add(new Client() { Name = "Frank" }); list.Add(john); list.Add(new Client() { Name = "Jay" }); radTreeListView1.ItemsSource = list; } } I don't get the exception.
Notice the only difference is I included both derived classes in the root collection in the working case, where as there was only a single derived class in the failing case.
The exception I am receiving is "Unable to cast object of type 'SilverlightApplication5.Client' to type 'SilverlightApplication5.Employee'."
The stack trace is:
at Telerik.Windows.Data.FuncExtensions.<>c__DisplayClass1`2.<ToUntypedFunc>b__0(Object item) at Telerik.Windows.Controls.GridViewBoundColumnBase.EvaluateIsReadOnlyState(Object item) at Telerik.Windows.Controls.GridViewBoundColumnBase.CanEdit(Object item) at Telerik.Windows.Controls.GridView.GridViewDataControl.BeginEdit(GridViewCell gridViewCell, RoutedEventArgs editingEventArgs) at Telerik.Windows.Controls.GridView.GridViewDataControl.OnCellMouseDown(GridViewCell cell, MouseButtonEventArgs args) at Telerik.Windows.Controls.GridView.GridViewCell.OnMouseLeftButtonDown(MouseButtonEventArgs e) at System.Windows.Controls.Control.OnMouseLeftButtonDown(Control ctrl, EventArgs e) at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName)One workaround I thought of was to included the second derived class for binding, then remove the second item right away, similar to:
Client jay = new Client() { Name = "Jay" }; list.Add(jay); radTreeListView1.ItemsSource = list; list.Remove(jay); However that doesn't appear to work...
A second more viable option might be a strategy pattern where there is only a single class in the grid, but this class delegates to the various derived classes. A "hack" but it should work.
Any thoughts?
In my actual use case there will only be one derived class in the grid's root, then a plethora of derived classes down the hierarchy of the grid...
Thanks
Jay