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

Button Command in RowDetailsTemplate does not work

1 Answer 603 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Glenn
Top achievements
Rank 1
Glenn asked on 20 Dec 2018, 10:01 AM

Hi, I'm relatively new in WPF and using the Telerik Controls. I'll go to my problem, I'm getting this error

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='Trial.ViewModel.DeviceViewModel', AncestorLevel='1''. BindingExpression:Path=SelectedField; DataItem=null; target element is 'RadGridView' (Name='BitField'); target property is 'SelectedItem' (type 'Object')

I appreciate your help in giving the solution to my problem.

So... this is my current setup:

ListView.xaml

<UserControl x:Class="Trial.Views.RegisterListView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:Trial.Views"
             xmlns:viewmodel="clr-namespace:Trial.ViewModel"
             xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
             xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="600">
    <Grid>
        <Grid.Resources>
            <DataTemplate x:Key="RowDetailsTemplate">
                <telerik:RadGridView Name="BitField" ItemsSource="{Binding Fields}" SelectedItem="{Binding Path=SelectedField, RelativeSource={RelativeSource AncestorType={x:Type viewmodel:DeviceViewModel}}}" AutoGenerateColumns="False" RowIndicatorVisibility="Collapsed">
                    <telerik:RadGridView.Columns>
                        <telerik:GridViewDataColumn DataMemberBinding="{Binding Name}"/>
                        <telerik:GridViewDataColumn DataMemberBinding="{Binding Value}"/>
                        <telerik:GridViewDataColumn Header="Command">
                            <telerik:GridViewDataColumn.CellEditTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal">
                                        <telerik:RadButton CornerRadius='15' Width="80" Height='30' Margin="10 10 0 0" ToolTip='Read Register' Content='Read' KeyboardNavigation.TabIndex="2" Command="{Binding Path=ReadRegisterCommand, RelativeSource={RelativeSource AncestorType={x:Type viewmodel:DeviceViewModel}}}"/>
                                    </StackPanel>
                                </DataTemplate>
                            </telerik:GridViewDataColumn.CellEditTemplate>
                        </telerik:GridViewDataColumn>
                        <telerik:GridViewDataColumn DataMemberBinding="{Binding Documentation}"/>
                    </telerik:RadGridView.Columns>
                </telerik:RadGridView>
            </DataTemplate>
        </Grid.Resources>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="300"/>
        </Grid.ColumnDefinitions>
        <telerik:RadGridView ItemsSource="{Binding Registers}" SelectedItem="{Binding SelectedRegister}" RowDetailsTemplate="{StaticResource RowDetailsTemplate}" AutoExpandGroups="False" RowIndicatorVisibility="Collapsed">
            <telerik:RadGridView.Columns>
                <telerik:GridViewToggleRowDetailsColumn/>
                <telerik:GridViewDataColumn Header="Register Name" DataMemberBinding="{Binding Name}"/>
                <telerik:GridViewDataColumn Header="Register Address" DataMemberBinding="{Binding Address}"/>
                <telerik:GridViewDataColumn Header="Register Value" DataMemberBinding="{Binding Value}"/>
                <telerik:GridViewDataColumn Header="Description" DataMemberBinding="{Binding Desc}"/>
            </telerik:RadGridView.Columns>
        </telerik:RadGridView>
    </Grid>
</UserControl>

=====================================================

DeviceViewModel.cs

public ObservableCollection<RegisterDetails> Registers
        {
            get
            {
                if (Registers != null)
                {
                    return this.Registers;
                }
                else
                {
                    return null;
                }
            }
        }

public RegisterDetails SelectedRegister
        {
            get
            {
                return this.selectedRegister;
            }

            set
            {
                this.selectedRegister = value;
                this.RaisePropertyChanged("SelectedRegister");
            }
        }

public FieldDetails SelectedField
        {
            get
            {
                return this.selectedField;
            }

            set
            {
                this.selectedField = value;
                this.RaisePropertyChanged("SelectedField");
            }
        }

=====================================================

RegisterDetails.cs

public class RegisterDetails
{
    public string Name { get; set; }
    public uint Address { get; set; }
    public uint Value { get; set; }
    public string Desc { get; set; }
    public FieldDetails[] Fields { get; set; }
}

=====================================================

FieldDetails.cs

public class FieldDetails
{
    public string Name { get; set; }
    public uint Value { get; set; }
    public string Documentation { get; set; }
}

1 Answer, 1 is accepted

Sort by
0
Yoan
Telerik team
answered on 24 Dec 2018, 07:10 AM
Hi Glenn,

In order to resolve the issue, the DeviceViewModel could be exposed as a static resource for the view and then you can set the exposed resource as a Source for the binding like so:

<UserControl.Resources>
       <viewmodel:DeviceViewModel x:Key="MyDeviceViewModel"/>
   </UserControl.Resources>
   <Grid DataContext="{StaticResource MyDeviceViewModel}">
       <Grid.Resources>
           <DataTemplate x:Key="RowDetailsTemplate">
               <telerik:RadGridView Name="BitField" ItemsSource="{Binding Fields}" SelectedItem="{Binding Path=SelectedField, Source={StaticResource MyDeviceViewModel}}" AutoGenerateColumns="False" RowIndicatorVisibility="Collapsed">
                   <telerik:RadGridView.Columns>
                       <telerik:GridViewDataColumn DataMemberBinding="{Binding Name}"/>
                       <telerik:GridViewDataColumn DataMemberBinding="{Binding Value}"/>
                       <telerik:GridViewDataColumn Header="Command">
                           <telerik:GridViewDataColumn.CellEditTemplate>
                               <DataTemplate>
                                   <StackPanel Orientation="Horizontal">
                                       <telerik:RadButton CornerRadius='15' Width="80" Height='30' Margin="10 10 0 0" ToolTip='Read Register' Content='Read' KeyboardNavigation.TabIndex="2" Command="{Binding Path=ReadRegisterCommand, RelativeSource={RelativeSource AncestorType={x:Type viewmodel:DeviceViewModel}}}"/>
                                   </StackPanel>
                               </DataTemplate>
                           </telerik:GridViewDataColumn.CellEditTemplate>
                       </telerik:GridViewDataColumn>
                       <telerik:GridViewDataColumn DataMemberBinding="{Binding Documentation}"/>
                   </telerik:RadGridView.Columns>
               </telerik:RadGridView>
           </DataTemplate>
       </Grid.Resources>
       <Grid.ColumnDefinitions>
           <ColumnDefinition Width="Auto"/>
           <ColumnDefinition Width="300"/>
       </Grid.ColumnDefinitions>
       <telerik:RadGridView ItemsSource="{Binding Registers}" SelectedItem="{Binding SelectedRegister}" RowDetailsTemplate="{StaticResource RowDetailsTemplate}" AutoExpandGroups="False" RowIndicatorVisibility="Collapsed">
           <telerik:RadGridView.Columns>
               <telerik:GridViewToggleRowDetailsColumn/>
               <telerik:GridViewDataColumn Header="Register Name" DataMemberBinding="{Binding Name}"/>
               <telerik:GridViewDataColumn Header="Register Address" DataMemberBinding="{Binding Address}"/>
               <telerik:GridViewDataColumn Header="Register Value" DataMemberBinding="{Binding Value}"/>
               <telerik:GridViewDataColumn Header="Description" DataMemberBinding="{Binding Desc}"/>
           </telerik:RadGridView.Columns>
       </telerik:RadGridView>
   </Grid>

Please note, that I had set the DataContext of the main grid to be the exposed view model. If you go with this approach, check if the data context is set in code behind and if yes, remove it.  

If you have any troubles with this binding, do not hesitate to contact me again, I will try to assist you further.

Regards,
Yoan
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
deri
Top achievements
Rank 1
commented on 09 Jul 2024, 10:09 AM | edited

Hi Telerik,

i know this topic is old, but now i am facing the same problem. I set the data context in another ViewModel, and i can't remove it because it could get so messy. Is there any patch update or something for this problem? I have no problem if the RowDetailsTemplate only read the data from the ViewModel, but when i need to Bind a Command (to delete a row for example) it just does not fire. Here is the portion of the RowDetailsTemplate : 


<telerik:GridViewDataColumn> <telerik:GridViewDataColumn.CellTemplate> <DataTemplate> <Grid> <telerik:RadButton Style="{StaticResource RadBtnMailStyle}" Content="Hapus" Width="90" Height="20" ToolTip="Hapus Rute"

Command="{Binding Path=DataContext.DeleteScenario, RelativeSource={RelativeSource AncestorType={x:Type telerik:RadGridView}}}" CommandParameter="{x:Static parameter:ContextMenuTypes.DeleteScenario}"

Visibility="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type telerik:GridViewRow}}, Converter={StaticResource bool2vis}}" > </telerik:RadButton> </Grid> </DataTemplate> </telerik:GridViewDataColumn.CellTemplate> </telerik:GridViewDataColumn>


Thanks.

Martin Ivanov
Telerik team
commented on 10 Jul 2024, 05:01 PM

If your DeleteScenario command is in the object assigned as DataContext of the RadGridView in the row details, then your current binding should work properly.

If you expect to bind to a command of the parent RadGridView's DataContext, then you can make the following change in the binding:

Command="{Binding Path=ParentRow.GridViewDataControl.DataContext.DeleteScenario, RelativeSource={RelativeSource AncestorType={x:Type telerik:RadGridView}}}"

I also attached a sample project that shows both approaches. I hope that helps.

deri
Top achievements
Rank 1
commented on 12 Jul 2024, 04:08 AM

Hi Martin,

Thanks for your reply, it works like a charms. It's a big help.

Thank you.

Tags
GridView
Asked by
Glenn
Top achievements
Rank 1
Answers by
Yoan
Telerik team
Share this question
or