This is a migrated thread and some comments may be shown as answers.

Can I programmatically search an tem in RadTreeListView in pure MVVM WPF application?

7 Answers 108 Views
TreeListView
This is a migrated thread and some comments may be shown as answers.
Eugene
Top achievements
Rank 1
Eugene asked on 28 Jun 2016, 01:28 PM

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

Sort by
0
Eugene
Top achievements
Rank 1
answered on 29 Jun 2016, 05:29 AM
Gentlemen, if you give me an example of C# WPF MVVM application where searching of specified item in RadTreeListView is realized, it'll be perfectly well. I will be very grateful to you for that. I again draw your attention that my application is pure MVVM one (without any code-behind) so that I can use there only the bound properties of RadTreeListView and mapped-on-commands events of RadTreeListView. I can't use methods of RadTreeListView in pure MVVM application because the instance of RadTreeListView is in the View and according to MVVM principles "ViewModel doesn't know about View". I am hope for your help.
0
Stefan
Telerik team
answered on 01 Jul 2016, 12:12 PM
Hello Eugene,

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
Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
0
Eugene
Top achievements
Rank 1
answered on 04 Jul 2016, 07:54 AM

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.

0
Stefan
Telerik team
answered on 05 Jul 2016, 12:21 PM
Hello 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
Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
0
Eugene
Top achievements
Rank 1
answered on 06 Jul 2016, 05:36 AM
Thank you very much, Stefan. I'll try binding 'View.RadTreeListView.SelectedItem --> ViewModel.SelectedRegister as you've adviced. I'll begin try it tomorrow (because just now I'm busy in another task). I will close the topic when I complete with the register search in RadTreeListView. OK.
0
Eugene
Top achievements
Rank 1
answered on 08 Jul 2016, 06:20 AM
Hi, Stefan. I've done register's search. It works. But I have a little problem hm... Is is the following. The flowmeter has about 1000 registers. On the screen (at the same time) a user can see in RadTreeListView about 25 registers. So, if the first register in the top of the RadTreeListView is selected, and a user asked a search of the last register in the end of the list then the search function finds the register perfectly, but there is no auto-scroll. So user must scroll to the found register (to see this register) manually with the mouse. How to automatically scroll the contents of the RadTreeListView to watch the register that was found? In MVVM application I can't use ScrollIntoView and ScrollIndexIntoView methods. Is there a way to auto scrolling to register found to watch it in MVVM? Thank you very much in advance.
0
Accepted
Stefan
Telerik team
answered on 08 Jul 2016, 02:17 PM
Hello Eugene,

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
Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
Tags
TreeListView
Asked by
Eugene
Top achievements
Rank 1
Answers by
Eugene
Top achievements
Rank 1
Stefan
Telerik team
Share this question
or