Установка Datacontext на contentpresenter: привязка внутри ContentTemplate не работает
Я изучаю WPF и шаблон MVVM и пытаюсь построить представление, подобное календарю. Таким образом, в настоящее время у меня есть сетка с 6 строками и 7 столбцами. Первая строка должна быть заголовком, таким образом, указывая дни недели, такие как " понедельник, вторник и т. д...' У меня есть следующее прямо сейчас в моем 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"/>
И так далее: вы видите схему, я думаю.
Вот CalendarHeaderCellTemplate
<DataTemplate x:Key="CalendarHeaderCellTemplate">
<StackPanel Margin="5" Background="Blue">
<TextBlock Text="{Binding}"></TextBlock>
</StackPanel>
</DataTemplate>
И вот важные части 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()};
}
Теперь ни Contentpresenter, где я определяю DataTemplate 'inline', не отображает ничего внутри своего TextBlock или CalendarHeaderCellTemplate.
Забавно, что внутри конструктора Visual Studio все отображается правильно, за исключением первой ячейки (т. е. той, в которой встроен шаблон)
У кого-нибудь есть предложение.
N. B. "встроенный" шаблон был в основном сделан для целей тестирования.
Править: Это делается (см. ниже) вместо использования ContentPresenter работать отлично. Может быть, я неправильно использую ContentPresenter?
<StackPanel Grid.Row="0" Grid.Column="0">
<TextBlock Text="{Binding DaysOfWeek[0]}"/>
</StackPanel>
Причина, по которой я хочу использовать ContentPresenter, заключается в том, что DataTemplate для содержимого каждой ячейки будет намного больше, чем просто текстовое поле.
2 ответа:
Попробуйте изменить свой ContentPresenter на
<ContentPresenter Content="{Binding DaysOfWeek[0]}" Grid.Row="0" Grid.Column="0"> <ContentPresenter.ContentTemplate> <DataTemplate> <TextBlock Text="{Binding}"/> </DataTemplate> </ContentPresenter.ContentTemplate> </ContentPresenter>
Или
<ContentPresenter Content="{Binding}" Grid.Row="0" Grid.Column="0"> <ContentPresenter.ContentTemplate> <DataTemplate> <TextBlock Text="{Binding DaysOfWeek[0]}"/> </DataTemplate> </ContentPresenter.ContentTemplate> </ContentPresenter>
А также замените свой DataContext содержимым типа
<ContentPresenter ContentTemplate="{StaticResource CalendarHeaderCellTemplate}" Grid.Row="0" Grid.Column="1" Content="{Binding DaysOfWeek[1]}"/>
Попробуйте использовать ContentControl вместо 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" />