I have an instance of RadTreeListView in my WPF MVVM Prism 6 application (my application is pure MVVM without code behind). I'm interested in searching of specified item in RadTreeListView in a programmatical way. The instance of RadTreeView in my application is bound to an instance of ObservableCollection comprising hierarchical data.
private ObservableCollection<ProfileElementType> _myCollection = new ObservableCollection<ProfileElementType>();// This property is the data source for RadTreeListView.public ObservableCollection<ProfileElementType> MyCollection{ get{return this _myCollection;} set{this.SetProperty(ref this._myCollection, value);}}ProfileElementType class is the base class for two classes that are derived from him. These derived classes are: Group and Register. The definition of ProfileElementType class, Group class and Register class you can see in my post in Stackoverflow at: http://stackoverflow.com/questions/37058259/why-is-invalideoperationexception-thrown-when-i-try-to-serialize-to-xml-an-obser . In "Hierarhy.PNG" attached file you can see how hierarchy is displayed in RadTreeView on the screen. In pure MVVM I can use only properties and mapped to commands events. But I can't use control's methods there. Is it possible to realize search in such RadTreeView in pure MVVM application?
P.S. If you need any additional Information please tell about it.
7 Answers, 1 is accepted
In case I am not missing something, you should be able to search for a given item directly in the source collection in the view model. In order to ensure that we are on the same page, can you please share more details on the exact requirement, so I can further assist you?
Best Regards,
Stefan X1
Telerik
OK, Stefan. First thank you very much for your support and help.You've written: "...can you please share more details on the exact requirement, so I can further assist you?". OK. I need in the function for searching of specified item (representing a device register) in RadTreeListView. This function should execute in the ViewModel and searches for a specified item (device register) directly in the source ObservableCollection to which RadTreeListView is bound in the View. However, if the search is successful, the found item (device register) must be selected in the RadTreeListView as current selected item. Below I present you some information about how to define data that is displayed in the RadTreeListView. Please see that RadTreeListView is bound to ObservableCollection as following:
<telerik:RadTreeListView x:Name="Hierarchical" Grid.Row="2" Grid.Column="0" AutoGenerateColumns="False" AutoExpandItems="True" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding ProfileTreeRoot.ChildProfileElenents}" Visibility="{Binding AreRegistersInHierarchyVisible}"> <telerik:RadTreeListView.ChildTableDefinitions> <telerik:TreeListViewTableDefinition ItemsSource="{Binding ChildProfileElenents}"/> </telerik:RadTreeListView.ChildTableDefinitions> <telerik:RadTreeListView.Columns> <telerik:GridViewDataColumn IsReadOnly="True" DataMemberBinding="{Binding Name}" Header="Наименование"> <telerik:GridViewDataColumn.CellStyle> <Style TargetType="{x:Type telerik:GridViewCell}"> <Setter Property="FontWeight" Value="SemiBold"/> </Style> </telerik:GridViewDataColumn.CellStyle> </telerik:GridViewDataColumn> <telerik:GridViewDataColumn DataMemberBinding="{Binding CurrentValue}" Header="Текущее значение"/> </telerik:RadTreeListView.Columns> <telerik:EventToCommandBehavior.EventBindings> <telerik:EventBinding Command="{Binding HandleProfileElementSelectionChangedCommand}" EventName="SelectionChanged" PassEventArgsToCommand="True"/> <telerik:EventBinding Command="{Binding HandleRowLoadedCommand}" EventName="RowLoaded" PassEventArgsToCommand="True"/> </telerik:EventToCommandBehavior.EventBindings></telerik:RadTreeListView>As you can see from XAML above, binding of RadTreeListView to datasource is:
ItemsSource="{Binding ProfileTreeRoot.ChildProfileElenents}"Where 'ProfileTreeRoot.ChildProfileElenents' is an ObservableCollection of hierarchical elements:
private ObservableCollection<ProfileElementType> _childProfileElenents;public ObservableCollection<ProfileElementType> ChildProfileElenents{ get { return this._childProfileElenents; } set { this._childProfileElenents = value; }}This collection comprises instances of 'ProfileElementType' class. Please see its definition below:
public class ProfileElementType : BindableBase, IProfileElementType{ #region Fields // Type name for the object's class that is derived from this class. // It can be one of the folowing: "Group" or "Register" or "Device". private string _elementTypeName; #endregion #region Properties // Gets or sets type name for the object's class that is derived from this class. public string ElementTypeName { get { return this._elementTypeName; } set { this._elementTypeName = value; } } #endregion #region IProfileElementType Implementation // Type of the object's class that is derived from this class. // It can be one of the folowing: Group or Register or Device. private Type _elementType; // Gets or sets type of the object's class that is derived from this class. public Type ElementType { get { return this._elementType; } set { this._elementType = value; } } #endregion}If you look at the picture in Hierarchical_2.PNG attached file you'll see two columns there: "Наименование" ("Name" in English) and "Текущее значение" ("Current Value" in English). Next, I will refer to these columns name in English (I bag your pardon for Russian headers). As you can see data in "Name" column has two levels of hierarchy. The first level is group names and the second level is register names. Each group can comprise some registers and some other groups. Each group of those that are shown in the picture is represented by Group class. Each register - by Register class. Below are definitions of these two clases. To very begin is definition of Group class:
public class Group : ProfileElementType{ #region Fields // The name of group private string name; // Brief description of group. private string description; // The collection of elements which are the children elements of this group. // These elements can be of Group class instances or Register class instances. private ObservableCollection<ProfileElementType> _childProfileElenents; // Parent group whose ChildProfileElenents collection comprises this Group instance. private Group parent; #endregion #region Constructors public Group() { this.ElementType = this.GetType(); this.ElementTypeName = this.ElementType.Name; this.Name = "Group 1"; this.ChildProfileElenents = new ObservableCollection<ProfileElementType>(); } #endregion #region Properties /// <summary> /// Gets or sets the name of the group. /// </summary> public string Name { get { return this.name; } set { this.SetProperty(ref this.name, value); } } /// <summary> /// Gets or sets the brief description of the group. /// </summary> public string Description { get { return this.description; } set { this.SetProperty(ref this.description, value); } } /// <summary> /// Gets or sets the collection of elements which are the children elements of this group. /// These elements can be of Group class instances or Register class instances /// </summary> public ObservableCollection<ProfileElementType> ChildProfileElenents { get { return this._childProfileElenents; } set { this.childProfileElenents = value; } } /// <summary> /// Gets or sets the parent group whose ChildProfileElenents collection comprises this Group instance. /// </summary> public Group Parent { get { return this.parent; } set { this.parent = value; } } #endregion}And here is the definition of Register class:
public class Register : ProfileElementType{ #region Fields private int number; private string name; private string description; private string currentValue; private string defaultValue; private string minimalValue; private string maximalValue; private string dataTypeName; private RegisterDataAccess accessToData; private Group parent; #endregion #region Constructors public Register() { this.ElementType = this.GetType(); this.ElementTypeName = this.ElementType.Name; this.Name = "REgister 1"; this.AccessToData = RegisterDataAccess.Read_Write; } #endregion #region Properties // Register's address in device. public int Number { get { return this.number; } set { this.SetProperty(ref this.number, value); } } // The name of the register. public string Name { get { return this.name; } set { this.SetProperty(ref this.name, value); } } // The breif description of the register. public string Description { get { return this.description; } set { this.SetProperty(ref this.description, value); } } // The register current value. public string CurrentValue { get { return this.currentValue; } set { this.SetProperty(ref this.currentValue, value); } } // The register default value. public string DefaultValue { get { return this.defaultValue; } set { this.SetProperty(ref this.defaultValue, value); } } // The register Minimal Value. public string MinimalValue { get { return this.minimalValue; } set { this.SetProperty(ref this.minimalValue, value); } } // The register Maximal Value. public string MaximalValue { get { return this.maximalValue; } set { this.SetProperty(ref this.maximalValue, value); } } // The register's value data type. public string DataTypeName { get { return this.dataTypeName; } set { this.SetProperty(ref this.dataTypeName, value); } } // The user access to register's data from application. public RegisterDataAccess AccessToData { get { return this.accessToData; } set { this.SetProperty(ref this.accessToData, value); } } // Parent group whose ChildProfileElenents collection comprises this Register instance. public Group Parent { get { return this.parent; } set { this.parent = value; } } #endregion}That is, under the guise of instances ProfileElementTipe the collection includes both Group class instances and Register class instances for displaying their information on the screen. So above I presented information to you which must give you understanding how to help me. I hope for your help very much.
Eugene.
Thanks for the update.
For this scenario, you can benefit from the SelectedItem property of RadTreeListView. You can define, for example, a SelectedRegister property in the view model and bind the aforementioned one of the control to it. When the search is performed, you can set the SelectedRegister property to be the found item.
You may also find the Stop Showing the Unfocused State help topic. It is for RadGridView, but the same approach applies to RadTreeListView as well.
Hope this helps.
Best Regards,
Stefan X1
Telerik by Progress
The built-in mechanism for such requirement is demonstrated in the Scrolling help topic. Can you please check it out?
Regards,
Stefan X1
Telerik by Progress