Getting selected row of a child grid

6 posts, 1 answers
  1. Adrian
    Adrian avatar
    6 posts
    Member since:
    Oct 2011

    Posted 06 Jun 2014 Link to this post

    I am having some issues getting the row that is selected in any child grid.

    My main grid is a grid of Manufacturers and each row can be expanded to view each manufacturer's parts. This is no problem. The problem is getting the current row with in each expanded child grid. Here is my code so far.

    public partial class ManufacturersAndPartsSearch : Window
       {
           private ViewModels.ManufacturersAndPartsSearchViewModel vm;
           public ManufacturersAndPartsSearch()
           {
               InitializeComponent();
               var context = new ViewModels.ManufacturersAndPartsSearchViewModel(this);
               this.vm = context;
               this.DataContext = vm;
     
               GridViewTableDefinition d = new GridViewTableDefinition();
               d.Relation = new Telerik.Windows.Data.PropertyRelation("ChildParts");
     
               //add child table defination to gridview
               this.GridView.ChildTableDefinitions.Add(d);
                
     
               this.GridView.DataLoaded += GridView_DataLoaded;
     
               //this is to alter changes to each child grid
               this.GridView.DataLoading += GridView_DataLoading;
     
               //event to check and set the view model's current row to a heirarchial's currently selected row if selected
     
               //explanation
               /*The original code used data binding to set the current row in the viewmodel equal to the current row in the grid
                this worked for the original purpose; however, since heirarchial grids are created for each row in the parent grid
                that has parts saved in the database then there is no way to bind their currently selected row properties to the viewmodel
                 
                The databinding was ditched and instead this route was taken which accounts for both types of grids*/
               this.GridView.SelectionChanged += GridView_SelectionChanged;
           }
     
           void GridView_SelectionChanged(object sender, SelectionChangeEventArgs e)
           {
               var grid = sender as RadGridView;
               var item = grid.SelectedItem;
               this.vm.CurrentItem = item;
               MessageBox.Show(item.GetType().ToString());
           }

    When my message box shows I always get a type of "PartsManufacturerViewModel". This would be correct in the parent grid because I am binding to my viewmodel's "ManufacturersAndPartsSearchViewModel.CurrentItem which is of type object. Since I am binding the grid to a collection of PartsManufacturerViewModels then this is expected. When I click on a child row I still get the same type but I should be getting PartViewModel, which is a property inside of PartsManufacturerViewModel. 

    The basic gist is this. PartsManufacturerViewModel holds data relevant to the manufacturer while it has a property called "ChildParts" which is a collection of PartViewModels (which hold data relevant to the part itself). It is this collection that I bind the ChildTableDefinitions to. 

    My desired outcome is to be able to set "this.vm.CurrentItem" to either a PartsManufacturerViewModel or a PartViewModel depending on the current row that is clicked once, either in the parent or the child grid.



    Here is the rest of my code (ViewModels) if it helps make things clearer.

    public class PartsManufacturerViewModel : Accu_Base_Lib.Bases.ModelViewModelBase<DAL.PartsManufacturer>
       {
     
     
           public string Id
           {
               get { return (string)GetValue(IdProperty); }
               set { SetValue(IdProperty, value); }
           }
     
           // Using a DependencyProperty as the backing store for Id.  This enables animation, styling, binding, etc...
           public static readonly DependencyProperty IdProperty =
               DependencyProperty.Register("Id", typeof(string), typeof(PartsManufacturerViewModel));
     
     
     
     
           public string Name
           {
               get { return (string)GetValue(NameProperty); }
               set { Debug.WriteLine("ViewModel Name Changed " + this.Name); SetValue(NameProperty, value); }
           }
     
           // Using a DependencyProperty as the backing store for Name.  This enables animation, styling, binding, etc...
           public static readonly DependencyProperty NameProperty =
               DependencyProperty.Register("Name", typeof(string), typeof(PartsManufacturerViewModel));
     
           private ObservableCollection<PartViewModel> _childParts;
     
           public ObservableCollection<PartViewModel> ChildParts
           {
               get
               {
                   if (this._childParts == null)
                   {
                       GetChildren();
                   }
     
                   return this._childParts;
               }
     
               set
               {
                   this._childParts = value;
               }
           }
     
            
           public PartsManufacturerViewModel(DAL.PartsManufacturer model)
                
           {
               base.Init(model);
               //Fills this viewmodel based off the model supplied.
               UpdateViewModelFromModel();
           }
     
           public PartsManufacturerViewModel()
           {
               base.Init();
               this.Model.Id = Guid.NewGuid().ToString();
               this.Model.Name = string.Empty;
               UpdateViewModelFromModel();
           }





    public class PartViewModel : Accu_Base_Lib.Bases.ModelViewModelBase<DAL.Part>
       {
     
     
           public string Id
           {
               get { return (string)GetValue(IdProperty); }
               set { SetValue(IdProperty, value); }
           }
     
           // Using a DependencyProperty as the backing store for Id.  This enables animation, styling, binding, etc...
           public static readonly DependencyProperty IdProperty =
               DependencyProperty.Register("Id", typeof(string), typeof(PartViewModel));
     
     
     
     
           public string ManufacturerId
           {
               get { return (string)GetValue(ManufacturerIdProperty); }
               set { SetValue(ManufacturerIdProperty, value); }
           }
     
           // Using a DependencyProperty as the backing store for ManufacturerId.  This enables animation, styling, binding, etc...
           public static readonly DependencyProperty ManufacturerIdProperty =
               DependencyProperty.Register("ManufacturerId", typeof(string), typeof(PartViewModel));
     
     
     
     
           public string Name
           {
               get { return (string)GetValue(NameProperty); }
               set { SetValue(NameProperty, value); }
           }
     
           // Using a DependencyProperty as the backing store for Name.  This enables animation, styling, binding, etc...
           public static readonly DependencyProperty NameProperty =
               DependencyProperty.Register("Name", typeof(string), typeof(PartViewModel));
     
     
     
     
           public string ModelNo
           {
               get { return (string)GetValue(ModelNoProperty); }
               set { SetValue(ModelNoProperty, value); }
           }
     
           // Using a DependencyProperty as the backing store for ModelNo.  This enables animation, styling, binding, etc...
           public static readonly DependencyProperty ModelNoProperty =
               DependencyProperty.Register("ModelNo", typeof(string), typeof(PartViewModel));
     
     
     
     
     
     
     
     
           public decimal Price
           {
               get { return (decimal)GetValue(PriceProperty); }
               set {
                   SetValue(PriceProperty, value); }
           }
     
           // Using a DependencyProperty as the backing store for Price.  This enables animation, styling, binding, etc...
           public static readonly DependencyProperty PriceProperty =
               DependencyProperty.Register("Price", typeof(decimal), typeof(PartViewModel));
     
            
     
            
     
            
     
     
           public PartViewModel(DAL.Part model)
                
           {
               base.Init(model);
               //Fills this viewmodel based off the model supplied.
               UpdateViewModelFromModel();
           }
     
           public PartViewModel()
           {
               base.Init();
               this.Model.Id = Guid.NewGuid().ToString();
               UpdateViewModelFromModel();
           }



  2. Adrian
    Adrian avatar
    6 posts
    Member since:
    Oct 2011

    Posted 06 Jun 2014 in reply to Adrian Link to this post

    And the reason I am trying to do this is to validate which buttons should be enabled or disabled using commands.
    This is the CanExecute method that enables/disables a button that allows for a new part to be added to the database. This can only happen if a Manufacturer is selected. If a part is selected then the button should be disabled.
    public override bool CanExecute(object parameter)
            {
                if (this.vm.CurrentItem == null)
                    return false;
                else if (this.vm.CurrentItem.GetType() != typeof(ViewModels.PartsManufacturerViewModel))
                    return false;
                else
                    return true;
            }
  3. Answer
    Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 06 Jun 2014 Link to this post

    Hi,

    You can bind the SelectedItem of your GridViews to this.vm.CurrentItem.
    That way the value in the ViewModel will be updated as soon as the user selects an item.

    Regards,
    Didie
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  4. Adrian
    Adrian avatar
    6 posts
    Member since:
    Oct 2011

    Posted 06 Jun 2014 in reply to Dimitrina Link to this post

    How would I bind to it from each child grid?

    <telerik:RadGridView Name="GridView"
                                 Grid.Row="1"
                                 CanUserDeleteRows="False"
                                 CanUserFreezeColumns="False"
                                 CanUserInsertRows="False"
                                 CanUserResizeColumns="True"
                                 CanUserReorderColumns="True"
                                 CanUserResizeRows="True"
                                 CanUserSortColumns="True"
                                 CanUserSortGroups="True"
                                 SelectionMode="Single"
                                 EnableRowVirtualization="True"
                                 EnableColumnVirtualization="True"
                                 FilteringMode="FilterRow"
                                 ItemsSource="{Binding DataContext}"
                                 SelectedItem="{Binding CurrentItem}"
                                 IsReadOnly="True"
                                 >
                <telerik:RadGridView.ChildTableDefinitions>
                    <telerik:GridViewTableDefinition>
                    </telerik:GridViewTableDefinition>
                </telerik:RadGridView.ChildTableDefinitions>
                <telerik:RadGridView.HierarchyChildTemplate>
                    <DataTemplate>
                        <telerik:RadGridView ItemsSource="{Binding ChildParts}"
                                             SelectedItem="{Binding CurrentItem}"/>
                    </DataTemplate>
                </telerik:RadGridView.HierarchyChildTemplate>
            </telerik:RadGridView>
  5. Adrian
    Adrian avatar
    6 posts
    Member since:
    Oct 2011

    Posted 06 Jun 2014 Link to this post

    WPF binding confuses me sometimes :p

    I got it to work using a relative source.

    <telerik:RadGridView ItemsSource="{Binding ChildParts}"
                                             SelectedItem="{Binding Path=DataContext.CurrentItem, Mode=OneWayToSource
                            , RelativeSource={RelativeSource AncestorType={x:Type telerik:RadGridView}}}"/>
  6. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 09 Jun 2014 Link to this post

    Hello,

    Having in mind RadGridView is a virtualized control, it is not recommended to work with the RelativeSource as the Name scope is not reliable.

    In order to get the Binding still be resolved in your case, you could specify a valid Source for it. You can define the ViewModels.ManufacturersAndPartsSearchViewModel as a StaticResource and then set it as a Source for the binding.

    Regards,
    Didie
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
Back to Top