在DataTemplate内部进行绑定?

3

我正在构建一款Silverlight控件,尝试通过它们各自的DataTemplates设置Header和Body ContentControls的绑定。但是,我不确定为什么这样做不起作用(默默失败)。我的唯一猜测是因为DataTemplates是StaticResources。有人可以提供建议吗?该控件具有以下默认模板:

<Style TargetType="local:LayoutItem">
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="local:LayoutItem">
            <StackPanel>
                <StackPanel.Resources>

                    <DataTemplate x:Key="DefaultHeaderTemplate">
                        <StackPanel>
                           <TextBlock Text="{Binding HeaderText}" FontSize="15"/>
                        </StackPanel>
                    </DataTemplate>

                    <DataTemplate x:Key="DefaultBodyTemplate">
                        <StackPanel>
                            <TextBlock Text="{Binding BodyText}" FontSize="12"/>
                        </StackPanel>
                    </DataTemplate>

                </StackPanel.Resources>

                <ContentControl x:Name="Header" 
                   ContentTemplate="{StaticResource DefaultHeaderTemplate}" />
                <ContentControl x:Name="Body" 
                   ContentTemplate="{StaticResource DefaultBodyTemplate}" />
            </StackPanel>
        </ControlTemplate>
   </Setter.Value>

谢谢!


更新

实际上,以下代码也不起作用,因此我的关于StaticResources的假设可能是错误的。

<ContentControl x:Name="Header">
<ContentControl.ContentTemplate>
    <DataTemplate x:Key="DefaultHeaderTemplate">
        <StackPanel>
            <TextBlock Text="{Binding HeaderText}" FontSize="15"  />
        </StackPanel>
    </DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>

控件的DataContext是否已经设置?您绑定的数据是否具有“HeaderText”和“BodyText”属性? - Jacob Adams
是的,我非常确定这是正确的。作为证明,我可以用<TextBlock Text="{Binding HeaderText}" FontSize="15" />替换ContentControl,它也能正常工作。 - Page
3个回答

3

很不情愿地回答自己的问题,但我终于解决了。实际上是由于其他地方出现了问题。供以后参考,以下代码对我有效:

<Style TargetType="local:LayoutItem">
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="local:LayoutItem">
            <StackPanel x:Name="LayoutRoot">
                <StackPanel.Resources>

                    <DataTemplate x:Key="DefaultHeaderTemplate">
                        <StackPanel>
                            <TextBlock FontSize="50" Text="{Binding Path=HeaderText}" />
                        </StackPanel>
                    </DataTemplate>

                </StackPanel.Resources>

                <ContentControl x:Name="Header" Content="{Binding}" ContentTemplate="{StaticResource DefaultHeaderTemplate}" />

            </StackPanel>
        </ControlTemplate>
    </Setter.Value>
</Setter>

请注意添加了Content="{Binding}"。这非常重要。 :)

Binding 中的 Path 不是多余的吗? - Nick Heiner
太棒了,正是我所缺少的。+1 - EightyOne Unite

1

您需要在某处设置页面的数据上下文。可以在代码后台完成

/// ctor
public MyClass()
{
   this.DataContext = ObjectThatIsDataContext;
}

或者在XAML中:

<UserControl ...>
    <UserControl.Resources>
       <myNS:MyClass x:Name="TheContext" x:Key="TheContext" />    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource TheContext}" >
        <TextBlock Text="{Binding Path=Field1}" />
    </Grid>
</UserControl>

另请参阅此篇文章


如上面的评论中所提到的,我已经设置了DataContext。 - Page

1

这在我的电脑上(3 Beta)可以运行:

        <ContentControl x:Name="Header">
            <ContentControl.ContentTemplate>
                <DataTemplate >
                    <StackPanel>
                        <TextBlock Text="{Binding HeaderText}" FontSize="15"  />
                    </StackPanel>
                </DataTemplate>
            </ContentControl.ContentTemplate>
            <ContentPresenter />
        </ContentControl>

然而,我不知道它为什么起作用...我以为是因为你可以将模板放在主持人周围,但后来又玩了一会儿,发现任何你包裹ContentPresenter的东西都会被完全忽略。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接