【问题标题】:Include a UserControl with Content包含带有内容的 UserControl
【发布时间】:2012-07-30 09:24:15
【问题描述】:

我创建了一个用户控件。我想将其包含在此代码中:

<UserControl1 Header="Heading">
    <TextBlock Text="My Content" />
</UserControl1>

这就是用户控件:

<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" />

我的第一种方式有什么问题?

【问题讨论】:

    标签: wpf xaml user-controls contentpresenter


    【解决方案1】:

    为了让事情按预期工作,您必须设置 UserControl 的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属性)。
    • 啊,我的错 - 你知道有一种方法可以绑定到在模板的 UserControl 代码隐藏中声明的自定义 DependencyProperty 吗?
    • 实际上只是想出了一个方法,但它的工作原理似乎令人惊讶。您可以使用 x:Name="someName" 命名 UserControl 元素,然后在模板的绑定中引用该名称,例如Text="{Binding ElementName=someName, Path=MyCustomDependencyProperty}".
    • @Brendan 实际上,这是在其自己的 XAML 中的绑定中访问控件本身的标准方法之一。另一种方法是RelativeSource,如(现在)在答案中所示。两者都比将控件的 DataContext 设置为自身要好。
    【解决方案2】:

    第一种方法没有任何错误。它只是创建一个UserControl1 并将内容设置为TextBlock,从而覆盖您在定义中设置的内容。第二种方法创建一个UserControl1 并保持内容不变。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-12
      • 2011-09-15
      • 1970-01-01
      • 1970-01-01
      • 2016-12-12
      • 1970-01-01
      • 2016-03-19
      相关资源
      最近更新 更多