包含一个具有内容的用户控件

3
我已经创建了一个用户控件。我想使用以下代码将其包含在内:
<UserControl1 Header="Heading">
    <TextBlock Text="My Content" />
</UserControl1>

这是UserControl:
<UserControl x:Class="WpfApplication1.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" MinHeight="200"
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <Style TargetType="ToggleButton">
            <!-- ... -->
        </Style>        
    </UserControl.Resources>
    <StackPanel>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding Path=Header}" Grid.Column="0" />
            <ToggleButton Name="ToggleButton" IsChecked="True" Grid.Column="2" />
        </Grid>
        <Rectangle Stroke="#c3c3c3" StrokeThickness="1" Height="1" StrokeDashArray="4 4" SnapsToDevicePixels="True" Focusable="False" />
        <!-- Content -->
        <ContentControl>
            <ContentPresenter/>
        </ContentControl>
    </StackPanel>
</UserControl>

现在来说说我的问题:
如果我使用以下代码进行集成,
<UserControl1 Header="Heading">
    <TextBlock Text="My Content" />
</UserControl1>

我收到的结果如下:

在此输入图像描述

这不是我想要的。

但是当我将其与此代码集成时,就得到了所需的结果。

<UserControls:UserControl1 Header="Heading" />

enter image description here

What's wrong at my first way?

2个回答

6
为了使事情按照您的期望工作,您需要设置用户控件的Template:
<UserControl x:Class="UserCtrl.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Template>
        <ControlTemplate TargetType="UserControl">
            <StackPanel>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0"
                        Text="{Binding Path=Header,
                               RelativeSource={RelativeSource Mode=FindAncestor,
                                               AncestorType=UserControl}}}" />
                    <ToggleButton Name="ToggleButton" IsChecked="True" Grid.Column="2" />
                </Grid>
                <Rectangle Stroke="#c3c3c3" StrokeThickness="1" Height="1" StrokeDashArray="4 4" SnapsToDevicePixels="True" Focusable="False" />
                <!-- Content -->
                <ContentPresenter/>
            </StackPanel>
        </ControlTemplate>
    </UserControl.Template>
    <!-- Initial Content of the UserControl -->
    <TextBlock Text="Initial Content"/>
</UserControl>

问题在于Header绑定将无法工作,因为ControlTemplate的目标是UserControl(它没有Header属性)。 - Brendan
啊,我的错 - 你知道如何从模板中绑定到在UserControl代码后台声明的自定义DependencyProperty吗? - Brendan
其实我刚刚想到了一种方法,但它似乎很令人惊讶地奏效了。您可以使用 x:Name="someName"UserControl 元素命名,然后在模板中引用该名称,例如 Text="{Binding ElementName=someName, Path=MyCustomDependencyProperty}" - Brendan
@Brendan 实际上这是在其自己的XAML中绑定访问控件本身的标准方式之一。另一种方法是使用RelativeSource,如答案所示。这两种方法都比将控件的DataContext设置为其本身更好。 - Clemens

0

第一种方式没有任何问题。它只是创建了一个UserControl1并将内容设置为TextBlock,从而覆盖了您在定义中设置的内容。第二种方式创建了一个UserControl1并保留原有内容。


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