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