Setting Datacontext on contentpresenter: Binding inside ContentTemplate is not working

23,640

Solution 1

Try changing your ContentPresenter to

    <ContentPresenter Content="{Binding DaysOfWeek[0]}" Grid.Row="0" Grid.Column="0">
        <ContentPresenter.ContentTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding}"/>
            </DataTemplate>
        </ContentPresenter.ContentTemplate>
    </ContentPresenter>

or

  <ContentPresenter Content="{Binding}" Grid.Row="0" Grid.Column="0">
        <ContentPresenter.ContentTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding DaysOfWeek[0]}"/>
            </DataTemplate>
        </ContentPresenter.ContentTemplate>
    </ContentPresenter>

and also replace your DataContext with Content like

<ContentPresenter ContentTemplate="{StaticResource CalendarHeaderCellTemplate}" Grid.Row="0" Grid.Column="1" Content="{Binding DaysOfWeek[1]}"/>

Solution 2

try using ContentControl rather than ContentPresenter

<Style x:Key="CalendarCell" TargetType="ContentControl">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="ContentControl">
        <StackPanel Margin="5" Background="{TemplateBinding Background}">
          <TextBlock Text="{TemplateBinding Content}" 
                     Foreground="{TemplateBinding Foreground}" />
        </StackPanel>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<!-- Header Row-->
<ContentControl Style="{StaticResource CalendarCell}" 
                Content="{Binding DaysOfWeek[0]}" 
                Background="Blue" 
                Foreground="White" />
<ContentControl Style="{StaticResource CalendarCell}" 
                Content="{Binding DaysOfWeek[1]}" 
                Background="Blue" 
                Foreground="White" 
                Grid.Column="1" />
<ContentControl Style="{StaticResource CalendarCell}" 
                Content="{Binding DaysOfWeek[2]}" 
                Background="Blue" 
                Foreground="White" 
                Grid.Column="2"  />
<ContentControl Style="{StaticResource CalendarCell}" 
                Content="{Binding DaysOfWeek[3]}" 
                Background="Blue" 
                Foreground="White" 
                Grid.Column="3"  />
<ContentControl Style="{StaticResource CalendarCell}" 
                Content="{Binding DaysOfWeek[4]}" 
                Background="Blue" 
                Foreground="White" 
                Grid.Column="4"  />
<ContentControl Style="{StaticResource CalendarCell}" 
                Content="{Binding DaysOfWeek[5]}" 
                Background="Blue" 
                Foreground="White" 
                Grid.Column="5"  />
<ContentControl Style="{StaticResource CalendarCell}" 
                Content="{Binding DaysOfWeek[6]}" 
                Background="Blue" 
                Foreground="White" 
                Grid.Column="6"  />

<!-- 1st Row-->
<ContentControl Style="{StaticResource CalendarCell}" 
                Content="" 
                Background="Wheat" 
                Foreground="Black" 
                Grid.Row="1"  />
<ContentControl Style="{StaticResource CalendarCell}" 
                Content="" 
                Background="Wheat" 
                Foreground="Black" 
                Grid.Column="1" 
                Grid.Row="1"  />
<ContentControl Style="{StaticResource CalendarCell}" 
                Content="" 
                Background="Wheat" 
                Foreground="Black" 
                Grid.Column="2" 
                Grid.Row="1"  />
<ContentControl Style="{StaticResource CalendarCell}" 
                Content="" 
                Background="Wheat" 
                Foreground="Black" 
                Grid.Column="3" 
                Grid.Row="1"  />
<ContentControl Style="{StaticResource CalendarCell}" 
                Content="" 
                Background="Wheat" 
                Foreground="Black" 
                Grid.Column="4" 
                Grid.Row="1"  />
<ContentControl Style="{StaticResource CalendarCell}" 
                Content="" 
                Background="Wheat" 
                Foreground="Black" 
                Grid.Column="5" 
                Grid.Row="1"  />
<ContentControl Style="{StaticResource CalendarCell}" 
                Content="" 
                Background="Wheat" 
                Foreground="Black" 
                Grid.Column="6" 
                Grid.Row="1"  />
Share:
23,640
Gilles Radrizzi
Author by

Gilles Radrizzi

Updated on July 30, 2022

Comments

  • Gilles Radrizzi
    Gilles Radrizzi almost 2 years

    I'm learning WPF and the MVVM Pattern and I'm trying to build a calendar-like view. So I currently have a Grid with 6 rows and 7 columns. The first row should be the Header, thus specifying the Week days like 'Monday, Tuesday, etc...' I have the following right now in my MonthView.xaml

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="{Binding RowHeight}"/>
            <RowDefinition Height="{Binding RowHeight}"/>
            <RowDefinition Height="{Binding RowHeight}"/>
            <RowDefinition Height="{Binding RowHeight}"/>
            <RowDefinition Height="{Binding RowHeight}"/>
            <RowDefinition Height="{Binding RowHeight}"/>
            <RowDefinition Height="{Binding RowHeight}"/>
        </Grid.RowDefinitions>
    
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="{Binding CellWidth}"/>
            <ColumnDefinition Width="{Binding CellWidth}"/>
            <ColumnDefinition Width="{Binding CellWidth}"/>
            <ColumnDefinition Width="{Binding CellWidth}"/>
            <ColumnDefinition Width="{Binding CellWidth}"/>
            <ColumnDefinition Width="{Binding CellWidth}"/>
            <ColumnDefinition Width="{Binding CellWidth}"/>
        </Grid.ColumnDefinitions>
    
        <!-- Header Row-->
        <ContentPresenter Grid.Row="0" Grid.Column="0">
            <ContentPresenter.ContentTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding DaysOfWeek[0]}"/>
                </DataTemplate>
            </ContentPresenter.ContentTemplate>
        </ContentPresenter>
        <ContentPresenter ContentTemplate="{StaticResource CalendarHeaderCellTemplate}" Grid.Row="0" Grid.Column="1" DataContext="{Binding DaysOfWeek[1]}"/>
        <ContentPresenter ContentTemplate="{StaticResource CalendarHeaderCellTemplate}" Grid.Row="0" Grid.Column="2" DataContext="{Binding DaysOfWeek[2]}"/>
        <ContentPresenter ContentTemplate="{StaticResource CalendarHeaderCellTemplate}" Grid.Row="0" Grid.Column="3" DataContext="{Binding DaysOfWeek[3]}"/>
        <ContentPresenter ContentTemplate="{StaticResource CalendarHeaderCellTemplate}" Grid.Row="0" Grid.Column="4" DataContext="{Binding DaysOfWeek[4]}"/>
        <ContentPresenter ContentTemplate="{StaticResource CalendarHeaderCellTemplate}" Grid.Row="0" Grid.Column="5" DataContext="{Binding DaysOfWeek[5]}"/>
        <ContentPresenter ContentTemplate="{StaticResource CalendarHeaderCellTemplate}" Grid.Row="0" Grid.Column="6" DataContext="{Binding DaysOfWeek[6]}"/>
    
        <!-- 1st Row-->
        <ContentPresenter ContentTemplate="{StaticResource CalendarCellTemplate}" Grid.Row="1" Grid.Column="0"/>
        <ContentPresenter ContentTemplate="{StaticResource CalendarCellTemplate}" Grid.Row="1" Grid.Column="1"/>
        <ContentPresenter ContentTemplate="{StaticResource CalendarCellTemplate}" Grid.Row="1" Grid.Column="2"/>
        <ContentPresenter ContentTemplate="{StaticResource CalendarCellTemplate}" Grid.Row="1" Grid.Column="3"/>
        <ContentPresenter ContentTemplate="{StaticResource CalendarCellTemplate}" Grid.Row="1" Grid.Column="4"/>
        <ContentPresenter ContentTemplate="{StaticResource CalendarCellTemplate}" Grid.Row="1" Grid.Column="5"/>
        <ContentPresenter ContentTemplate="{StaticResource CalendarCellTemplate}" Grid.Row="1" Grid.Column="6"/>
    

    On so on: You see the pattern I guess.

    Here's the CalendarHeaderCellTemplate

    <DataTemplate x:Key="CalendarHeaderCellTemplate">
        <StackPanel Margin="5" Background="Blue">
            <TextBlock Text="{Binding}"></TextBlock>
        </StackPanel>
    </DataTemplate>
    

    And here's the important parts of the ViewModel:

     public ObservableCollection<string> DaysOfWeek { get; private set; }
     public MonthViewModel()
        {  
            this.DaysOfWeek = new ObservableCollection<string> {DayOfWeek.Monday.ToString(), DayOfWeek.Tuesday.ToString(), DayOfWeek.Wednesday.ToString(), 
                DayOfWeek.Thursday.ToString(), DayOfWeek.Friday.ToString(), DayOfWeek.Saturday.ToString(), DayOfWeek.Sunday.ToString()};
    
        }
    

    Now neither the Contentpresenter where I define the DataTemplate 'inline' does display anything inside its TextBlock nor the CalendarHeaderCellTemplate.

    Funny thing is, inside the Visual Studio designer, everything show up correctly, except for the first cell (i.e. the one with the inline template)

    Does anyone have a suggestion.

    N.B. The 'inline' template was mostly done for testing purposes.

    EDIT: Doing this (see below) instead of using the ContentPresenter works fine. Maybe I use the ContentPresenter in a wrong manner?

     <StackPanel Grid.Row="0" Grid.Column="0">
         <TextBlock Text="{Binding DaysOfWeek[0]}"/>
     </StackPanel>
    

    The reason I want to use a ContentPresenter is because the DataTemplate for the content of every cell is going to be much more than just a textbox in the end.

  • Gilles Radrizzi
    Gilles Radrizzi over 13 years
    Great. That did the trick. Just changing DataContext to Content. I'm heading to MSDN right now to check on the ContentPresenter.Content property :-)
  • Gilles Radrizzi
    Gilles Radrizzi over 13 years
    Dean's answer also did the trick. Now I'm wondering which is one of both answers it the way to go i.e. will leave me more flexibility later on?
  • Dean Chalk
    Dean Chalk over 13 years
    ContentPresenter is really designed for use inside control templates, so I would recommend ContentControl
  • Joshua Frank
    Joshua Frank over 4 years
    @biju: Why do we we need to set Content when it's the data?