【问题标题】:Setting Datacontext on contentpresenter: Binding inside ContentTemplate is not working在 contentpresenter 上设置 Datacontext:ContentTemplate 内的绑定不起作用
【发布时间】:2011-05-30 08:00:33
【问题描述】:

我正在学习 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()};

    }

现在,我定义 DataTemplate 'inline' 的 Contentpresenter 既不会在其 TextBlock 内显示任何内容,也不会在 CalendarHeaderCellTemplate 中显示任何内容。

有趣的是,在 Visual Studio 设计器中,所有内容都正确显示,除了第一个单元格(即具有内联模板的单元格)

有人有什么建议吗。

注意“内联”模板主要用于测试目的。

编辑: 这样做(见下文)而不是使用 ContentPresenter 可以正常工作。也许我以错误的方式使用 ContentPresenter?

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

我想使用 ContentPresenter 的原因是因为每个单元格内容的 DataTemplate 最终将不仅仅是一个文本框。

【问题讨论】:

    标签: wpf xaml datacontext contentpresenter


    【解决方案1】:

    尝试将您的 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 替换为 Content like

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

    【讨论】:

    • 太棒了。那成功了。只需将 DataContext 更改为 Content。我现在要去 MSDN 检查 ContentPresenter.Content 属性:-)
    • @biju:为什么要设置Content是数据?
    【解决方案2】:

    尝试使用 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"  />
    

    【讨论】:

    • Dean 的回答也起到了作用。现在我想知道哪个是两个答案之一,即以后会给我更多的灵活性?
    • ContentPresenter 确实是为在控件模板中使用而设计的,所以我会推荐 ContentControl
    猜你喜欢
    • 2017-07-14
    • 2013-12-21
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    • 2012-12-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多