ContentTemplate 中绑定和 DataContext 的混淆

2023-12-10

考虑以下样式:

<Window.Resources>
    <Style x:Key="NumberButton" TargetType="Button">
        <Setter Property="Width" Value="Auto"/>
        <Setter Property="Height" Value="Auto"/>
        <Setter Property="Margin" Value="2"/>
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Label Content="{Binding}" FontSize="20" FontFamily="Consolas"/>
                </DataTemplate>
            </Setter.Value>
        </Setter>
        <EventSetter Event="Click" Handler="OnClicked"/>
    </Style>
</Window.Resources>

我的目标是能够创建多个按钮,每个按钮代表一个数字 0-9。例如,这里是数字 0 的按钮:

<Button Grid.Row="3" Grid.Column="1" Style="{StaticResource NumberButton}" Content="0"/>

我对 DataContext 工作原理的理解是,如果您未在 XAML 中显式设置它,则它应该为 NULL,这指示绑定改为使用父级的 DataContext。这是传递性的,因此它将继续向上移动每个父级,直到找到要使用的显式设置的 DataContext。

然而,我对我的绑定如何映射到Content属性。我知道ContentControl的默认属性是Content属性,但我从未明确设置DataContext on the <Button>元素。对我来说,这意味着按钮的 DataContext 为 NULL,因此它将无法找到要显示的值。

有人可以解释一下当我没有设置按钮的 DataContext 时如何引用它吗?


The DataContext of the <ContentTemplate>的特殊之处在于它被设置为Content对象的属性<ContentTemplate>正在被应用到。

在这种情况下,ContentTemplate正在应用于一个Button, 所以DataContext在 - 的里面ContentTemplate被设置为Content那的财产Button, and Button.Content被设定为"0"

如果你应用这个ContentTemplate到一个不同的Button与不同的Content财产,即Content将使用属性来代替。

这是一个简单的例子,我希望能更好地演示这一点。

<Button x:Name="OuterButton" Click="Button_Click">
    <!-- // Set DataContext to a string equal to "OuterButton.DataContext" -->
    <Button.DataContext>
        OuterButton.DataContext
    </Button.DataContext>

    <!-- // Set Content to a string equal to "OuterButton.DataContext" -->
    <Button.Content>
        OuterButton.Content
    </Button.Content>

    <Button.ContentTemplate>
        <DataTemplate>
            <StackPanel>
                <Button x:Name="InnerButton" Content="InnerButton.Content" Click="Button_Click" />
                <TextBlock FontWeight="Bold" Text="{Binding }"/>
            </StackPanel>
        </DataTemplate>
    </Button.ContentTemplate>
</Button>
private void Button_Click(object sender, RoutedEventArgs e)
{
    Button btn = sender as Button;
    Debug.WriteLine(string.Format("{0}.DataContext: {1}", btn.Name, btn.DataContext));
    Debug.WriteLine(string.Format("{0}.Content: {1}", btn.Name, btn.Content));
}

我们这里有一个按钮。按钮的DataContext and Content属性设置为不同的值。该按钮还有一个ContentTemplate定义,其中包含另一个Button。这个按钮的Content属性设置为不同的值。

单击任一按钮将输出Content and DataContext被单击的按钮的。请记住,内部按钮嵌套在 OuterButton 内部,因此当您单击它时,将为两个按钮处理 Click 方法。

点击内部按钮的最终结果:



InnerButton.DataContext: OuterButton.Content
InnerButton.Content: InnerButton.Content

OuterButton.DataContext: OuterButton.DataContext
OuterButton.Content: OuterButton.Content
  

如您所见,一个ContentTemplate的特殊之处在于它设置了DataContext to the Content它所应用到的任何对象的属性。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ContentTemplate 中绑定和 DataContext 的混淆 的相关文章

随机推荐