请考虑以下样式:
<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>
Run Code Online (Sandbox Code Playgroud)
我的目标是能够创建多个按钮,每个按钮代表一个0-9的数字.例如,这是数字0的按钮:
<Button Grid.Row="3" Grid.Column="1" Style="{StaticResource NumberButton}" Content="0"/>
Run Code Online (Sandbox Code Playgroud)
我对DataContext如何工作的理解是,如果你没有在XAML中显式设置它,它应该是NULL,它指示绑定使用父的DataContext.这是可传递的,因此它将继续向上移动每个父级,直到找到要使用的显式设置的DataContext.
然而,我对我的绑定如何映射到Content属性感到困惑.我知道ContentControl的默认属性是Content财产,但我从来没有明确设置DataContext上<Button>的元素.对我来说,这意味着Button的DataContext为NULL,因此无法找到要显示的值.
有人可以解释当我没有设置Button时如何引用Button的DataContext?
它DataContext的<ContentTemplate>特殊之处在于它被设置为要应用Content的对象的属性<ContentTemplate>.
在这种情况下,ContentTemplate正在应用于a Button,因此将其DataContext内部ContentTemplate设置为该Content属性Button,并将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>
Run Code Online (Sandbox Code Playgroud)
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));
}
Run Code Online (Sandbox Code Playgroud)
我们这里有一个按钮.Button DataContext和Content属性设置为不同的值.该按钮还有一个已ContentTemplate定义的,其中包含另一个Button.此按钮的Content属性设置为不同的值.
单击任一按钮将输出单击的按钮Content和DataContext.请记住,内部按钮嵌套在OuterButton中,因此当您单击它时,将为两个按钮处理Click方法.
单击内部按钮的最终结果:
InnerButton.DataContext: OuterButton.Content InnerButton.Content: InnerButton.Content OuterButton.DataContext: OuterButton.DataContext OuterButton.Content: OuterButton.Content
正如您所看到的,a ContentTemplate的特殊之处在于它将其应用于任何对象DataContext的Content属性设置为.