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

[Solved] How do I get the selected Item in a HierarchyChildTemplate

9 Answers 799 Views
GridView
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Martin
Top achievements
Rank 1
Martin asked on 27 Sep 2010, 10:20 AM
Hello,

how can I get the SelectedItem of a HierachyChildTemplate?

I defined it as

<telerik:RadGridView HorizontalAlignment="Left" Name="radGridView1" CanUserInsertRows="False" CanUserDeleteRows="False" ReorderColumnsMode="None" ShowColumnHeaders="True" ShowGroupPanel="False" CanUserResizeColumns="True" CanUserSelect="True" Width="389" Height="486" Grid.RowSpan="10" LayoutUpdated="radGridView1_LayoutUpdated" CanUserFreezeColumns="False" RowLoaded="RadGridView1_RowLoaded" DataLoading="RadGridView1_DataLoading"  IsReadOnly="True" AutoGenerateColumns="False" SelectedItem="{Binding SelectedItem,Mode=TwoWay}">
            <telerik:RadGridView.ChildTableDefinitions>
              <telerik:GridViewTableDefinition>
                    <telerik:GridViewTableDefinition.Relation>
                        <telerik:PropertyRelation ParentPropertyName="Property"/>
                    </telerik:GridViewTableDefinition.Relation>
                </telerik:GridViewTableDefinition>
            </telerik:RadGridView.ChildTableDefinitions>
            <telerik:RadGridView.HierarchyChildTemplate>
                <DataTemplate>
                    <telerik:RadGridView RowLoaded="radGridView1_RowLoaded_1" x:Name="childgrid" CanUserFreezeColumns="False" AutoGenerateColumns="False" ItemsSource="{Binding Property}" ShowGroupPanel="False" IsReadOnly="True" IsSynchronizedWithCurrentItem="True" SelectedItem="{Binding DataContext.SelectedItem,Mode=TwoWay,ElementName=radGridView1}" >
                        <telerik:RadGridView.Columns>
                            <telerik:GridViewDataColumn Header="Color" DataMemberBinding="{Binding Color}">
                                <telerik:GridViewDataColumn.CellTemplate>
                                    <DataTemplate>
                                        <Border Width="30" Height="20" Background="{Binding Color}"/>
                                    </DataTemplate>
                                </telerik:GridViewDataColumn.CellTemplate>
                            </telerik:GridViewDataColumn>
                            <telerik:GridViewDataColumn Header="Name" DataMemberBinding="{Binding Name}">
                            </telerik:GridViewDataColumn>
                            <telerik:GridViewDataColumn Header="Default" DataMemberBinding="{Binding IsDefault}">
                            </telerik:GridViewDataColumn>
                        </telerik:RadGridView.Columns>
                    </telerik:RadGridView>
                </DataTemplate>
            </telerik:RadGridView.HierarchyChildTemplate>
         <telerik:RadGridView.Columns>
             <telerik:GridViewDataColumn Header="Color" DataMemberBinding="{Binding Color}">
                    <telerik:GridViewDataColumn.CellTemplate>
                        <DataTemplate>
                            <Border Width="30" Height="20" Background="{Binding Color}"/>
                        </DataTemplate>
                    </telerik:GridViewDataColumn.CellTemplate>
                </telerik:GridViewDataColumn>
                       <telerik:GridViewDataColumn Header="Name" DataMemberBinding="{Binding Name}">
                </telerik:GridViewDataColumn>
                <telerik:GridViewDataColumn Header="Default" DataMemberBinding="{Binding Default}">
                </telerik:GridViewDataColumn>
            </telerik:RadGridView.Columns>
        </telerik:RadGridView>

but I need a way to find the child Selected Item. I tried it with binding and all other methods I can think of but it still does not work. I found an old post of Milan which I tried to, no luck.

Can anyone help me out with this?

9 Answers, 1 is accepted

Sort by
0
Maya
Telerik team
answered on 27 Sep 2010, 01:06 PM
Hello Martin,

There are a couple of possible approaches to get the SelectedItem depending on your particular scenario. You may expose a custom Property and bind it to the SelectedItem Property of the child grid. However, if you want to proceed in this manner, you will have to define the class with that custom Property as a Resource and then use it as a StaticResource, when setting the Source Property of the Binding.
Furthermore, in order to provide you with the most appropriate solution, I would need a bit more information about your exact requirements.
 

Greetings,
Maya
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Martin
Top achievements
Rank 1
answered on 28 Sep 2010, 09:48 AM
Hello,

the exact requirements are:

I select one of the child or parent row. With a special button aside I can delete or change the object. The button for the parent and child row is the same. It should detect which object is clicked and then open the appropriate dialog.
That works. But I run into problems getting the "right" child row. I use

childGrid = (RadGridView)sender;
in the CurrentCellChanged Event of the Childgrid but it does not select every time the "right" child table and so it does not detect the selected child row.
And one other thing: I want that in the whole table only one row (no matter if it is child table or not) can be selected. I think that will be solvable as soon as I have a solution for my SelectedItem-Problem.

I hope you can provide me with a solution for that problem.

Thanks,

Martin
0
Maya
Telerik team
answered on 01 Oct 2010, 12:19 PM
Hello Martin,

I am sending you a sample project illustrating an implementation of a mechanism for selecting only a single row in every grid. Basically, you need to handle the SelectionChanged event like:

private void clubsGrid_SelectionChanged(object sender, SelectionChangeEventArgs e)
{          
    if (changingSelection)
        return;
    changingSelection = true;
    var dataControl = e.OriginalSource as GridViewDataControl;
    var selectedItem = dataControl.SelectedItem;
 
    this.UnSelect();
    dataControl.SelectedItems.Add(selectedItem);
    changingSelection = false;
}

The UnSelect() method is as follows:
private void UnSelect()
{
    this.clubsGrid.UnselectAll();
 
    foreach(GridViewRow row in this.clubsGrid.ChildrenOfType<GridViewRow>())
    {
        if(row != null && row.IsExpanded == true)
        {
            RadGridView childGrid = row.ChildrenOfType<RadGridView>().FirstOrDefault();
            childGrid.UnselectAll();
        }
    }
}


Thus you will be able to save the selected-at-the-moment item and un-select all the others. You may see the sample project for further reference.
 


Best wishes,
Maya
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Martin
Top achievements
Rank 1
answered on 01 Oct 2010, 01:41 PM
Thank you very much.

That works, I found the error. I have to refresh the grid when I change something. I used radgridview.Rebind(); but that seems to affect the SelectedItems in an unknown way.

How can I refresh the Datagrid to Display the new values then?

Martin
0
Maya
Telerik team
answered on 01 Oct 2010, 03:09 PM
Hi Martin,

Unfortunately, I am not quite sure what your exact scenario is and when the grid is supposed to refresh. Thus I would need more details about your requirements so that I could provide you with an accurate solution. 
 

Sincerely yours,
Maya
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Martin
Top achievements
Rank 1
answered on 01 Oct 2010, 03:27 PM
Hi,

I worked around this problem by binding it directly to the database.

But one problem remains

You said before
"You may expose a custom Property and bind it to the SelectedItem Property of the child grid. However, if you want to proceed in this manner, you will have to define the class with that custom Property as a Resource and then use it as a StaticResource, when setting the Source Property of the Binding."

Can you explain that to me more, eventually with a little example? I don`t understand it all :-(

Thanks,

Martin
0
Maya
Telerik team
answered on 04 Oct 2010, 09:07 AM
Hi Martin,

I have updated the sample project I sent to you previously. It exposes two possible ways for achieving that functionality. In the first case the SelectedItem Property is bound to a Property defined in the ViewModel, in the second case - to a property defined in the class supplying the child grid. You may choose the more appropriate depending on your scenario.

Kind regards,
Maya
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Rob
Top achievements
Rank 1
answered on 31 Oct 2010, 10:09 PM
Hello Maya - 
I downloaded your last code sample and I was wondering if it is possible to bind the SelectedItem of the child grid to an exposed property in the ViewModel. I have tried this with no success...I can bind the parent grid to an exposed property and I can see the set method being called on the property as I select a new row. When I try this for the child grid, it does not work. 

Here is the xaml:
<UserControl x:Class="FullRide.Modules.GlobalAdministration.Views.LookupView"
             xmlns:telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls"
             xmlns:Controls="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView"
             xmlns:Controls1="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Navigation"
             mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="800">
 
 
 
    <telerik:RadBusyIndicator Name="radBusyIndicator1" BusyContent="Please Wait..." IsBusy="{Binding IsBusy, Mode=TwoWay}"  >       
        <Grid x:Name="LayoutRoot" Background="White">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Border BorderBrush="#FF5A5151" BorderThickness="1">
                <Controls:RadGridView Margin="5,5,5,5" IsReadOnly="True" ShowGroupPanel="False" Height="300" ItemsSource="{Binding LookupGroupResults, Mode=TwoWay}" SelectedItem="{Binding SelectedLookupGroup, Mode=TwoWay}" AutoGenerateColumns="False" VerticalAlignment="Top">
                     
                    <Controls1:RadContextMenu.ContextMenu>
                        <Controls1:RadContextMenu x:Name="contextMenu">
                            <Controls1:RadMenuItem Header="Edit" Command="{Binding ButtonCommand}" CommandParameter="Edit" />
                            <Controls1:RadMenuItem Header="Delete" Command="{Binding ButtonCommand}" CommandParameter="Delete" />
                        </Controls1:RadContextMenu>
                    </Controls1:RadContextMenu.ContextMenu>
 
                    <Controls:RadGridView.Columns>
                        <Controls:GridViewDataColumn Header="LookupGroupID" DataMemberBinding="{Binding LookupGroupID}" MinWidth="50"></Controls:GridViewDataColumn>
                        <Controls:GridViewDataColumn Header="Group Name" DataMemberBinding="{Binding GroupName}" MinWidth="150"></Controls:GridViewDataColumn>
                        <Controls:GridViewDataColumn Header="Group Description" DataMemberBinding="{Binding GroupDescription}" MinWidth="150"></Controls:GridViewDataColumn>
                        <Controls:GridViewDataColumn Header="System Group" DataMemberBinding="{Binding IsSystemGroup}" MinWidth="100"></Controls:GridViewDataColumn>
                        <Controls:GridViewDataColumn Header="Lookup Group Key" DataMemberBinding="{Binding LookupGroupKey}" MinWidth="100"></Controls:GridViewDataColumn>
                        <Controls:GridViewDataColumn Header="Active" DataMemberBinding="{Binding Active}" MinWidth="100"></Controls:GridViewDataColumn>
                    </Controls:RadGridView.Columns>
                     
                    <Controls:RadGridView.ChildTableDefinitions>
                        <Controls:GridViewTableDefinition x:Name="childGridDefinition"/>
                    </Controls:RadGridView.ChildTableDefinitions>
                     
                    <Controls:RadGridView.HierarchyChildTemplate>
                        <DataTemplate>
                            <Controls:RadGridView Margin="5,5,5,5" IsReadOnly="True" Height="150" ShowGroupPanel="False" ItemsSource="{Binding LookupValues, Mode=TwoWay}" SelectedItem="{Binding SelectedLookupValue, Mode=TwoWay}" AutoGenerateColumns="False">
                                <Controls:RadGridView.Columns>
                                    <Controls:GridViewDataColumn Header="LookupValueID" DataMemberBinding="{Binding LookupID}" MinWidth="50"></Controls:GridViewDataColumn>
                                    <Controls:GridViewDataColumn Header="LookupGroupID" DataMemberBinding="{Binding LookupGroupID}" MinWidth="50"></Controls:GridViewDataColumn>
                                    <Controls:GridViewDataColumn Header="LookupValue" DataMemberBinding="{Binding Value}" MinWidth="50"></Controls:GridViewDataColumn>                                   
                                    <Controls:GridViewColumn >
                                        <Controls:GridViewColumn.CellTemplate >
                                            <DataTemplate>
                                                <Button Content="Edit" Command="{Binding ButtonCommand}" CommandParameter="EditValue"></Button>
                                            </DataTemplate>
                                        </Controls:GridViewColumn.CellTemplate>
                                    </Controls:GridViewColumn>
                                </Controls:RadGridView.Columns>
                            </Controls:RadGridView>
                        </DataTemplate>                       
                    </Controls:RadGridView.HierarchyChildTemplate>                   
                </Controls:RadGridView>
            </Border>
            <StackPanel Grid.Row="1" Margin="5" Orientation="Horizontal" HorizontalAlignment="Right">
                <Button Content="Edit" HorizontalAlignment="Right" Height="25" Width="75" Margin="5" Grid.Row="1" VerticalAlignment="Top" CommandParameter="Edit" Command="{Binding ButtonCommand}"  />
                <Button Content="Delete" HorizontalAlignment="Right" Height="25" Width="75" Margin="5" Grid.Row="1" VerticalAlignment="Top" CommandParameter="Delete" Command="{Binding ButtonCommand}"/>
            </StackPanel>
        </Grid>
    </telerik:RadBusyIndicator>
</UserControl>
    

and here is the viewModel:
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Windows;
using ArchitectNow.ClientFramework;
using ArchitectNow.ClientFramework.Silverlight.Telerik.Services;
using ArchitectNow.ClientFramework.UI;
using FullRide.Entities.DataAccess;
using Telerik.Windows.Controls;
 
namespace FullRide.Modules.GlobalAdministration.Views
{
    [Document(true, 1)]
    public class LookupViewModel : BaseViewModel
    {
        private SecurityContext _context;
        private RelayCommand _buttonCommand = null;
        private LookupGroup _selectedLookupGroup = null;
        private LookupValue _selectedLookupValue = null;
 
        private ObservableCollection<LookupGroup> _lookupGroupResults = new ObservableCollection<LookupGroup>();
        /// <summary>
        /// Gets or sets the lookup group results.
        /// </summary>
        /// <value>The lookup group results.</value>
        public ObservableCollection<LookupGroup> LookupGroupResults
        {
            get { return _lookupGroupResults; }
            set { SetObject(ref _lookupGroupResults, value, "LookupGroupResults"); }
        }
 
        /// <summary>
        /// Gets or sets the selected Lookup Group.
        /// </summary>
        /// <value>The selected LookupGroup.</value>
        public LookupGroup SelectedLookupGroup
        {
            get { return _selectedLookupGroup; }
            set
            {  
                SetObject(ref _selectedLookupGroup, value, "SelectedLookupGroup");
                ButtonCommand.UpdateCanExecuteState();
            }
        }
 
 
        public LookupValue SelectedLookupValue
        {
            get { return _selectedLookupValue; }
            set
            {
                SetObject(ref _selectedLookupValue, value, "SelectedLookupValue");
                 
 
            }
        }
 
        /// <summary>
        /// Gets the button command.
        /// </summary>
        /// <value>The button command.</value>
        public RelayCommand ButtonCommand
        {
            get
            {
                if (_buttonCommand == null)
                {
                    _buttonCommand = new RelayCommand(
                        x => x != null && x.ToString().Length > 0 && CheckCommandAvailable(x.ToString()),
                        x => ExecuteCommand(x.ToString()));
                }
                return _buttonCommand;
            }
        }
 
        public override object Initialize(object Parameters)
        {
            Title = "Lookup View";
            LoadLookupGroupData();
            return null;
        }
 
        /// <summary>
        /// Loads the Lookup Group data.
        /// </summary>
        private void LoadLookupGroupData()
        {
            IsReady = false;
 
            _context = new SecurityContext();
            var _operation = _context.Load(_context.GetLookupGroupsAndValuesQuery());
            _operation.Completed += new EventHandler(LoadLookupGroups_Loaded);
        }
 
        /// <summary>
        /// Handles the Loaded event of the Load Lookup Group control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void LoadLookupGroups_Loaded(object sender, EventArgs e)
        {
            LookupGroupResults = new ObservableCollection<LookupGroup>();
 
            LoadOperation<LookupGroup> _operation = (LoadOperation<LookupGroup>)sender;
            if (!_operation.HasError && _operation.Entities.Count() != 0)
            {
                foreach (var lu in _operation.Entities)
                {
                    LookupGroupResults.Add(lu);
                }
            }
            IsReady = true;
        }
 
        /// <summary>
        /// Checks the command available.
        /// </summary>
        /// <param name="CommandParameter">The command parameter.</param>
        /// <returns></returns>
        public bool CheckCommandAvailable(string CommandParameter)
        {
            switch (CommandParameter)
            {
                case "Edit":
                    return SelectedLookupGroup != null;
                case "Delete":
                    return SelectedLookupGroup != null;
                default:
                    return false;
            }
        }
 
        /// <summary>
        /// Executes the command.
        /// </summary>
        /// <param name="CommandParamter">The command paramter.</param>
        public void ExecuteCommand(string CommandParamter)
        {
            switch (CommandParamter)
            {
                case "Load":
                    LoadLookupGroupData();
                    break;
                case "Edit":
                    if (SelectedLookupGroup != null)
                    {
                        AppContext.Current.ViewService.GetViewManager("Dialog").ShowView(typeof(LookupViewModel), SelectedLookupGroup.LookupGroupID);
                    }
                    else
                    {
                        RadWindow.Alert("Lookup Group must be selected");
                    }
                    break;
                case "Delete":
                    if (SelectedLookupGroup != null)
                    {
                        DeleteLookupGroup();
                    }
                    else
                    {
                        RadWindow.Alert("Lookup Group must be selected");
                    }
                    break;
                default:
                    RadWindow.Alert("Unknown command parameter '" + CommandParamter + "'");
                    break;
            }
        }
 
         
        /// <summary>
        /// Deletes the Selected LookupGroup
        /// </summary>
        private void DeleteLookupGroup()
        {
            if (MessageBox.Show("Are you sure you want to delete this Lookup Group", "Delete Lookup Group?", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
            {
                _context.LookupGroups.Remove(SelectedLookupGroup);
                _context.SubmitChanges().Completed += new EventHandler(DeleteLookupGroup_Completed);
            }
        }
 
        /// <summary>
        /// Reloads the data after the delete is complete
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DeleteLookupGroup_Completed(object sender, EventArgs e)
        {
            LoadLookupGroupData();
        }
    }
}


The LookupValues data property in the child grid is a child table in the LookupGroup Entity. In order to get the SelectedItem to work for the child grid do I need to use a fully qualified name or something? Thanks in advance.

Rob



0
Maya
Telerik team
answered on 03 Nov 2010, 04:20 PM
Hi Rob,

You may try to set the Source property in the Binding of the SelectedItem in the child grid. For example:

public class MyViewModel : INotifyPropertyChanged
{
   private Player selectedPlayer;
        public Player SelectedPlayer
        {
            get
            {
                return this.selectedPlayer;
            }
            set
            {
                if (value != this.selectedPlayer)
                {
                    this.selectedPlayer = value;
                    this.OnPropertyChanged("SelectedPlayer");
                }
            }
        }
...
}

<UserControl.Resources>
    <my:MyViewModel x:Key="MyViewModel"/>
</UserControl.Resources>

<telerik:RadGridView Name="playersGrid"                                                                              ItemsSource="{Binding Players}"                                         SelectedItem="{Binding SelectedPlayer, Mode=TwoWay, Source={StaticResource MyViewModel}}"                                   AutoGenerateColumns="False">
 

All the best,
Maya
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
GridView
Asked by
Martin
Top achievements
Rank 1
Answers by
Maya
Telerik team
Martin
Top achievements
Rank 1
Rob
Top achievements
Rank 1
Share this question
or