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
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.
Maya
the Telerik team
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;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
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.
Maya
the Telerik team
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
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.
Maya
the Telerik team
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
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.
Maya
the Telerik team
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
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">Maya
the Telerik team