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

[Solved] How to find element in CellTemplate of GridViewDatacolumn in managed code

2 Answers 494 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.
Zeeshan
Top achievements
Rank 1
Zeeshan asked on 13 Jul 2011, 11:08 AM
Hi,
I am trying to create a Slverlight Control Library in which I am using the telerik RadGridView.
I am facing issues finding the element in one of the column, in the Control Class of that element
the design code goes like this:

<Style TargetType="Controls:AdministrativeControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Controls:AdministrativeControl">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition Height="50" />
                        </Grid.RowDefinitions>
                        <telerik:RadGridView x:Name="UnApprovedCommentsList" AutoGenerateColumns="False" Grid.Row="0"  >
                            <telerik:RadGridView.Columns>
                                <telerik:GridViewDataColumn Header="Select" DataMemberBinding="{Binding IsApproved}">
                                    <telerik:GridViewDataColumn.CellTemplate>
                                        <DataTemplate>
                                            <CheckBox x:Name="SelectCheckBox" Tag="{Binding Id}" IsChecked="{Binding IsApproved}"  />
                                        </DataTemplate>
                                    </telerik:GridViewDataColumn.CellTemplate>
                                </telerik:GridViewDataColumn>
 
                                <telerik:GridViewDataColumn Header="Comment Contents" DataMemberBinding="{Binding Message}" MaxWidth="500" TextWrapping="Wrap" IsReadOnly="True">
                                    <telerik:GridViewDataColumn.CellTemplate>
                                        <DataTemplate>
                                            <telerik:RadRichTextBox x:Name="UnapprovedCommentRichTextBox" IsSpellCheckingEnabled="False" IsReadOnly="True" >
                                                <telerik:RadRichTextBox.Resources>
                                                    <Html:HtmlDataProvider x:Key="htmlDataProvider" RichTextBox="{Binding ElementName=UnapprovedCommentRichTextBox}" Html="{Binding Path=Message, Mode=OneWay}"/>
                                                </telerik:RadRichTextBox.Resources>
                                            </telerik:RadRichTextBox>
                                        </DataTemplate>
                                    </telerik:GridViewDataColumn.CellTemplate>
                                </telerik:GridViewDataColumn>
                                <telerik:GridViewDataColumn Header="Author" DataMemberBinding="{Binding CommentAuthor.Name}" IsReadOnly="True"/>
                                <telerik:GridViewDataColumn Header="Email" DataMemberBinding="{Binding CommentAuthor.Email}" IsReadOnly="True"/>
                                <telerik:GridViewDataColumn Header="Site" DataMemberBinding="{Binding CommentAuthor.Site}" IsReadOnly="True"/>
                                <telerik:GridViewDataColumn Header="IP Address" DataMemberBinding="{Binding CommentAuthor.IP}" IsReadOnly="True"/>
                                <telerik:GridViewDataColumn Header="Location" DataMemberBinding="{Binding CommentAuthor.Location}" IsReadOnly="True"/>
                                <telerik:GridViewDataColumn Header="Delete" >
                                    <telerik:GridViewDataColumn.CellTemplate>
                                        <DataTemplate>
                                            <telerik:RadButton x:Name="btnCommentDelete" Tag="{Binding Id}" Height="23" Width="100" Content="Delete"  />
                                        </DataTemplate>
                                    </telerik:GridViewDataColumn.CellTemplate>
                                </telerik:GridViewDataColumn>
                            </telerik:RadGridView.Columns>
 
                        </telerik:RadGridView>
                        <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
                            <telerik:RadButton x:Name="btnApprove"  Height="25" Width="100" Content="Approve" Margin="10"  />
                            <telerik:RadButton x:Name="btnDelete"  Height="25" Width="100" Content="Delete" Margin="10" />
                            <telerik:RadButton x:Name="btnCancel"  Height="25" Width="100" Content="Cancel" Margin="10" />
                        </StackPanel>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Now  UnapprovedCommentsList is a RadGridView in our case here which have several columns defined.
What I need is the CheckBox named "SelectCheckBox" and the RadButton named "btnCommentDelete" in the first and last column of RadGridView so that I can bind some event handlers on their clicks etc.

The Steps I followed:
Normally if you want to find an element in the design while creating the control library, then what you do is you write something like this

public override void OnApplyTemplate()
        {
            if (_isTemplateApplied) return;
            base.OnApplyTemplate();
 
            UnApprovedCommentsList = GetTemplateChild("UnApprovedCommentsList") as RadGridView;
 
            ...
            ...
            ...
            ...
 
            _isTemplateApplied = true;
        }

which works fine in my case till the time I am finding the UnApprovedCommentsList RadGridView, however the problem Intensifies when I try to find the elements inside the ColumnTemplate (or celltemplate or Itemtemplate or by whatevener name it is known as)

This is what happens:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Telerik.Windows.Controls;
 
namespace RobustHaven.Modules.Library
{
    public class AdministrativeControl : Control
    {
        private bool _isTemplateApplied;
        private CheckBox SelectCheckBox;
        private RadGridView UnApprovedCommentsList;
        private static List<int> SelectedIds = new List<int>();
 
        public AdministrativeControl()
        {
            _isTemplateApplied = false;
            DefaultStyleKey = typeof(AdministrativeControl);
 
        }
 
        public override void OnApplyTemplate()
        {
            if (_isTemplateApplied) return;
            base.OnApplyTemplate();
 
            UnApprovedCommentsList = GetTemplateChild("UnApprovedCommentsList") as RadGridView;
 
            try { SelectCheckBox = GetTemplateChild("SelectCheckBox") as CheckBox; }
            catch { }
 
            try { SelectCheckBox = SearchFrameworkElement(UnApprovedCommentsList, "SelectCheckBox") as CheckBox; }
            catch { }
 
            try { SelectCheckBox = UnApprovedCommentsList.FindName("SelectCheckBox") as CheckBox; }
            catch { }
 
            try { SelectCheckBox = UnApprovedCommentsList.FindChildByType<CheckBox>(); }
            catch { }
 
            try { SelectCheckBox = ((UnApprovedCommentsList.Columns[0] as GridViewDataColumn).CellTemplate).FindChildByType<CheckBox>(); }
            catch { }
 
            try { var visuals = GetVisuals(UnApprovedCommentsList); }
            catch { }
 
            _isTemplateApplied = true;
        }
 
        
        public static IEnumerable<DependencyObject> GetVisuals(DependencyObject root)
        {
            int count = VisualTreeHelper.GetChildrenCount(root);
 
            for (int i = 0; i < count; i++)
            {
                var child = VisualTreeHelper.GetChild(root, i);
 
                yield return child;
 
                foreach (var descendants in GetVisuals(child))
                {
                    yield return descendants;
                }
            }
        }
     
 
        public static FrameworkElement SearchFrameworkElement(FrameworkElement parentFrameworkElement, string childFrameworkElementNameToSearch)
        {
            FrameworkElement childFrameworkElementFound = null;
            SearchFrameworkElement(parentFrameworkElement, ref childFrameworkElementFound, childFrameworkElementNameToSearch);
            return childFrameworkElementFound;
        }
 
        //SearchFrameworkElement helper
        private static void SearchFrameworkElement(FrameworkElement parentFrameworkElement, ref FrameworkElement childFrameworkElementToFind, string childFrameworkElementName)
        {
            int childrenCount = VisualTreeHelper.GetChildrenCount(parentFrameworkElement);
            if (childrenCount > 0)
            {
                FrameworkElement childFrameworkElement = null;
                for (int i = 0; i < childrenCount; i++)
                {
                    childFrameworkElement = (FrameworkElement)VisualTreeHelper.GetChild(parentFrameworkElement, i);
                    if (childFrameworkElement != null && childFrameworkElement.Name.Equals(childFrameworkElementName))
                    {
                        childFrameworkElementToFind = childFrameworkElement;
                        return;
                    }
                    SearchFrameworkElement(childFrameworkElement, ref childFrameworkElementToFind, childFrameworkElementName);
                }
            }
        }
    }
}

I tried finding the SelectCheckBox in the number of ways as in the code above
1st, 2nd, 3rd and 4rd try gives me null value.
5th try throws errors saying that "Reference is not a valid visual DependencyObject."
6th try says that there is nothing inside the RadGridView "Enumeration yielded no results".


I simply want each checkbox and the radbutton of every row to be bound to some Event Handler.
Am I trying to do something which is not possible on this planet or is it only not possible in the world of telerik ?

2 Answers, 1 is accepted

Sort by
0
Pavel Pavlov
Telerik team
answered on 13 Jul 2011, 12:28 PM
Hello Zeeshan,

If you just need to handle the event , you do not need to traverse the visual tree  to find the control , can't you can simply set the event handler  in XAML in the datatemplate itself ?.


Let me know which event you need handled and I will provide you with some code.

In case you insist on traversing the visual tree to find the checkbox  I can still give you solution.  However please have in mind that RadGridView renders only cells visible in the viewport at the moment .In other words - you will get only the controls visible  and if there is a vertical scrollbar - the rest of the controls bellow the viewport will remain hidden  and inaccessible ( until the user scrolls down) . 


Greetings,
Pavel Pavlov
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Zeeshan
Top achievements
Rank 1
answered on 13 Jul 2011, 02:34 PM
Hi Pavel,
I want to set the checked and the unchecked events on the checkbox.
What I am trying to create is a custom control, when we create a custom control, the things are little different, we don't really have a .cs file behind .xaml to handle the events.
I have a generic.xaml resource dictionary which have the style of the custom control and then .cs file is the  class of that custom control (AdministrativeControl in my case)
You can attach here your sample code if you think its relevant in this type of scenario.
Tags
GridView
Asked by
Zeeshan
Top achievements
Rank 1
Answers by
Pavel Pavlov
Telerik team
Zeeshan
Top achievements
Rank 1
Share this question
or