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

Binding header text

8 Answers 214 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Andrew
Top achievements
Rank 1
Andrew asked on 02 May 2011, 05:46 PM
I'm binding a column header's text to a property on my view-model (i.e. the grid's DataContext). I think I have it working now, but it seems like the solution should have been simpler. Can someone please tell me if there's a better solution?

Here's how I got it to work. Basically one column header contains a GridFinder, which provides access to the DataContext of the grid, and all the columns bind to it by element name.

(For brevity, some code is omitted, and only one column is shown.)
<telerik:RadGridView
    x:Name="ScheduleGrid"
    ItemsSource="{Binding Schedules}"
    >
    <telerik:RadGridView.Columns>
        <telerik:GridViewDataColumn>
            <telerik:GridViewDataColumn.Header>
                <StackPanel>
                    <ce:GridFinder x:Name="GridFinder" />
                    <TextBlock
                        DataContext="{Binding ParentGridView.DataContext, ElementName=GridFinder}"
                        Text="{Binding DayOfWeek1}"
                        />
                </StackPanel>
            </telerik:GridViewDataColumn.Header>
        </telerik:GridViewDataColumn>
    </telerik:RadGridView.Columns>
</telerik:RadGridView>

Here's the code for GridFinder, most of which was copied from this forum post by Dave Curylo.

public class GridFinder : FrameworkElement
{
    public GridViewDataControl ParentGridView { get; private set; }
 
    public GridFinder()
    {
        this.Loaded += (s, re) =>
        {
            this.ParentGridView = GetContainingGrid(this);
        };
    }
 
    private GridViewDataControl GetContainingGrid(DependencyObject value)
    {
        if (value != null)
        {
            DependencyObject parent = VisualTreeHelper.GetParent(value);
            if (parent != null)
            {
                GridViewRow gridViewRow = parent as GridViewRow;
                if (gridViewRow != null)
                {
                    return gridViewRow.GridViewDataControl;
                }
                else
                {
                    GridViewDataControl grid = parent as GridViewDataControl;
                    if (grid != null)
                    {
                        return grid;
                    }
                    else
                    {
                        return GetContainingGrid(parent);
                    }
                }
            }
            else
            {
                return null;
            }
        }
        return null;
    }
}

Here are some other things I tried, which did not work:

<telerik:GridViewDataColumn>
    <telerik:GridViewDataColumn.Header>
        <TextBlock Text="{Binding DataContext.DayOfWeek1, ElementName=ScheduleGrid}" />
    </telerik:GridViewDataColumn.Header>
</telerik:GridViewDataColumn>

<telerik:GridViewDataColumn
    Header="{Binding DataContext.DayOfWeek1, ElementName=ScheduleGrid}"
    />

<telerik:GridViewDataColumn
    Header="{Binding DayOfWeek1}"
    />

I also tried adding a new dependency property, HeaderBinding, to a class that inherits from RadGridView. It updates Header whenever HeaderBinding's value changes. That didn't seem to be the way to go either, and didn't always work.

8 Answers, 1 is accepted

Sort by
0
Maya
Telerik team
answered on 02 May 2011, 05:51 PM
Hello Andrew,

You may set directly the Source property of the binding. For example, if you set your ViewModel to be the DataContext of the main Grid, you may bind the Header as follows:

<TextBlock Text="{Binding DayOfWeek1, Source={StaticResource MyViewModel}"  />

Do let me know whether this solution fits into your requirements.
 

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
Andrew
Top achievements
Rank 1
answered on 02 May 2011, 06:05 PM
Hello Maya,

Thanks for the quick response. I have seen examples that do that, and my project contains several UserControls that declare a view-model as a static resource. However, in this case, I have a UserControl inside another UserControl. My original post was in the context of EmployeeSchedulesWeekly, but here's the basic structure of the parent UserControl.

<UserControl>
    <UserControl.Resources>
        <ce:EmployeeSchedulesMainViewModel x:Key="MainViewModel" />
    </UserControl.Resources>
 
    <Grid DataContext="{StaticResource MainViewModel}">
        <controls:TabControl>
            <controls:TabItem>
                <ce:EmployeeSchedulesWeekly DataContext="{Binding WeeklyScheduleViewModel}" />
            </controls:TabItem>
            <controls:TabItem>
                <ce:EmployeeSchedulesDaily DataContext="{Binding DailySchedulesViewModel}" />
            </controls:TabItem>
        </controls:TabControl>
    </Grid>
</UserControl>
0
Maya
Telerik team
answered on 03 May 2011, 03:12 PM
Hi Andrew,

In order to skip any misunderstandings, I would need a bit more details on the topic. May you clarify where exact is the RadGridView - in some of the RadTabItem-s probably? Furthermore, where is defined the property to which you want to bind your Header ? Why exactly is it not possible to set the corresponding ViewModel as a StaticResource ? Generally, may you provide any additional relevant information that will comprise the whole structure of your application ?
 

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
Andrew
Top achievements
Rank 1
answered on 03 May 2011, 06:36 PM
Hi Maya,

Yes, the grid is inside one of the tabs.

It might be possible to make my ViewModel a StaticResource of the EmployeeSchedulesWeekly control. If so, then I could certainly use the solution you provided. (In fact, that's the way it was initially.) I'll keep that option in mind, but basically I switched so that my main view-model could interact with the two sub-view-models (WeeklyScheduleViewModel and DailyScheduleViewModel).

I think the core of my question is this: If a grid's DataContext is set to an object that exposes property P, is it possible for me to declare a column header that contains a control that's bound to property P? (As you can see from my original post, I tried ElementName= and that didn't work.)
0
Maya
Telerik team
answered on 04 May 2011, 08:02 AM
Hello Andrew,

You have to explicitly set the DataContext of the Header to be the one of grid and afterwards, you may bind the Text property directly to the one defined there:

<Grid x:Name="LayoutRoot"
         Background="White"
         DataContext="{StaticResource MyViewModel}">
<telerik:RadGridView Name="clubsGrid"
                            ItemsSource="{Binding Clubs}"
                            AutoGenerateColumns="False">
           <telerik:RadGridView.Columns>
               <telerik:GridViewToggleRowDetailsColumn/>
               <telerik:GridViewDataColumn DataMemberBinding="{Binding Name}">
                   <telerik:GridViewDataColumn.Header>
                       <TextBlock Text="{Binding MyHeaderTextProperty}" DataContext="{StaticResource MyViewModel}" />
                   </telerik:GridViewDataColumn.Header>
       </telerik:GridViewDataColumn>  
           </telerik:RadGridView.Columns>
       </telerik:RadGridView>       
   </Grid>


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
Andrew
Top achievements
Rank 1
answered on 05 May 2011, 10:47 PM
Hi Maya,

I see now that my previous post was a bit unclear. I've tweaked your code sample to try to show what I'm after.

Notice that DataContext is not set explicitly on the Grid or the RadGridView, so it's being inherited from something higher up in the visual tree. I want to bind the TextBlock to a property of the RadGridView's DataContext. If this is not possible, then I'll either stick with my workaround or change my design so that an instance of my view-model is declared as a StaticResource.

<Grid x:Name="LayoutRoot"
         Background="White">
<telerik:RadGridView Name="clubsGrid"
                            ItemsSource="{Binding Clubs}"
                            AutoGenerateColumns="False">
           <telerik:RadGridView.Columns>
               <telerik:GridViewToggleRowDetailsColumn/>
               <telerik:GridViewDataColumn DataMemberBinding="{Binding Name}">
                   <telerik:GridViewDataColumn.Header>
                       <TextBlock Text="{Binding MyHeaderTextProperty}" DataContext="{Binding DataContext, ElementName=clubsGrid}" />
                   </telerik:GridViewDataColumn.Header>
       </telerik:GridViewDataColumn
           </telerik:RadGridView.Columns>
       </telerik:RadGridView>      
   </Grid>
0
Accepted
Maya
Telerik team
answered on 09 May 2011, 11:44 AM
Hi Andrew,

It is not possible to bind the DataContext of the nested TextBlock to the one of the grid. What you may try is either to expose your ViewModel as StaticResource or to use a DataContextProxy to bind to the other element's DataContext.


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
Andrew
Top achievements
Rank 1
answered on 09 May 2011, 03:00 PM
Thanks Maya, I appreciate your help!
Tags
GridView
Asked by
Andrew
Top achievements
Rank 1
Answers by
Maya
Telerik team
Andrew
Top achievements
Rank 1
Share this question
or