WPF ContentPresenter 覆盖同一级别的其他控件

WPF ContentPresenter overrides othe Controls on the same level

在我的最后一个问题中,我将重新创建一个扩展器 + 它是切换按钮。

扩展器模板:

<ControlTemplate TargetType="Expander">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="15"/>
        </Grid.RowDefinitions>
        <ContentPresenter x:Name="ContentPresenter" Grid.Row="0"/>
        <ToggleButton Grid.Row="1" >
           ....
        </ToggleButton>
    </Grid>

现在,当我在主视图中使用此自定义控件并添加一个控件(例如按钮)时:

<custom:FullWidthExpander Width="200" HeaderBackground="Gray">
    <Button />
</custom:FullWidthExpander>

切换按钮(在我上面的扩展器模板中定义)被此按钮覆盖。

当您执行此操作时,这意味着用户控件的全部内容都将替换为您提供的内容。

<custom:FullWidthExpander Width="200" HeaderBackground="Gray">
    <Button />
</custom:FullWidthExpander>

要解决这个问题,您需要在用户控件中以稍微不同的方式托管内容

首先为用户控件添加一个依赖属性

    public object UserControlContent
    {
        get { return (object)GetValue(UserControlContentProperty); }
        set { SetValue(UserControlContentProperty, value); }
    }

    public static readonly DependencyProperty UserControlContentProperty =
        DependencyProperty.Register("UserControlContent", typeof(object), typeof(FullWidthExpander),
          new PropertyMetadata(null));

然后将其绑定到用户控件中的 contentpresenter xaml 还为您的用户控件定义一个名称,例如 x:Name="Root".

<Expander Header="My expander header">
    <Expander.Template>
        <ControlTemplate>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="15"/>
                </Grid.RowDefinitions>

                <ContentPresenter x:Name="ContentPresenter" Grid.Row="0" Content="{Binding UserControlContent, ElementName=Root}" />

                <ToggleButton Grid.Row="1" Content="Togglebutton">

                </ToggleButton>
            </Grid>
        </ControlTemplate>
    </Expander.Template>
</Expander>

最后在 maindwindow xaml 中定义内容

<custom:FullWidthExpander>
    <custom:FullWidthExpander.UserControlContent>
        <Button Content="Click me"/>
    </custom:FullWidthExpander.UserControlContent>
</custom:FullWidthExpander>

您是否将 UserControl.Content 绑定到 Expander.Content 属性?

<!-- define a custom Template for the UserControl FullWidthExpander -->
<UserControl.Template>
    <ControlTemplate TargetType="UserControl">
        <!-- be sure to include the Content binding to pass the UC.Content to Expander -->
        <Expander Content="{TemplateBinding Content}">
            <!-- create a custom Template for this Expander -->
            <Expander.Template>
                <ControlTemplate TargetType="Expander">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition x:Name="ContentRow" Height="*"/>
                            <RowDefinition Height="20"/>
                        </Grid.RowDefinitions>
                        <ContentPresenter Grid.Row="0" Content="{TemplateBinding Content}"/>
                        <ToggleButton Grid.Row="1" Content="Test Toggle Button" />
                    </Grid>
                </ControlTemplate>
            </Expander.Template>
        </Expander>
    </ControlTemplate>
</UserControl.Template>

我做了一个快速测试,当使用这样的控件时效果很好:

<local:FullWidthExpander>
    <Button Content="Test Content Button"/>
</local:FullWidthExpander>

我也看了一下 ,如果您在这里有 ControlTemplate.Triggers 那么您还需要确保将 Expander.IsExpanded 设置为 True为了查看您的内容。如果 IsExpanded=False,您的触发器将隐藏顶部内容行,这是扩展器的默认设置。