【问题标题】:WPF Expander Templating - Display Content above ToggleButtonWPF 扩展器模板 - 在 ToggleButton 上方显示内容
【发布时间】:2016-01-19 14:45:43
【问题描述】:

我即将通过创建不同的模板来创建一个新的扩展器控件(学习目的),但无法弄清楚我做错了什么......

切换按钮模板:

<ToggleButton>
    <ToggleButton.Template>
        <ControlTemplate TargetType="ToggleButton">
            <Border x:Name="eBB" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                <Grid>
                    <Path x:Name="Sign" Data="M 0,10 L 7.5,2.5 L 15, 10" Stroke="Black" Width="15">
                        <Path.RenderTransform>
                            <RotateTransform Angle="0"/>
                        </Path.RenderTransform>
                    </Path>
                </Grid>
            </Border>
            <ControlTemplate.Triggers>
                <Trigger Property="IsChecked" Value="True">
                    <Setter Property="Data" TargetName="Sign" Value="M 0,2.5 L 7.5,10 L 15,2.5"/>
                </Trigger>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Stroke" Value="#222" TargetName="Sign"/>
                    <Setter Property="Background" Value="#666" TargetName="eBB"/>
                </Trigger>
                <Trigger Property="IsPressed" Value="True">
                    <Setter Property="Stroke" Value="#FF003366" TargetName="Sign"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </ToggleButton.Template>
</ToggleButton>

扩展模板:

<Expander>
    <Expander.Template>
        <ControlTemplate TargetType="Expander">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition x:Name="ContentRow" Height="*"/>
                    <RowDefinition Height="20"/>
                </Grid.RowDefinitions>
                <ContentPresenter Grid.Row="0" Visibility="Collapsed" Content="{TemplateBinding Content}"/>
                <local:FullSizeExpanderToggleButton Grid.Row="1" />
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="IsExpanded" Value="True">
                    <Setter Property="Visibility" Value="Visible"/>
                    <Setter Property="Height" Value="*" TargetName="ContentRow"/>
                </Trigger>
                <Trigger Property="IsExpanded" Value="False">
                    <Setter Property="Height" Value="0" TargetName="ContentRow"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Expander.Template>
</Expander>

现在当我想在主视图中添加扩展器时:

<custom:FullSizeExpander Width="300">
            <Button/>
        </custom:FullSizeExpander>

Control 内部的整个空间都被 Button 填充(ToggleButton 不再可见)。

我做错了什么?

另外我有一些关于这个问题的问题:

  1. “ContentSource="Content"” 有什么作用?它是干什么用的?与“Content="{Templatebinding Content}"”有什么不同?
  2. 当 ToggleButtons 属性“IsPressed”发生变化时,Expander 的“IsExpanded”属性是否也会发生变化?如果扩展器中根本没有切换按钮怎么办?

【问题讨论】:

  • 您应该考虑将文本缩减为一个问题。我不想回答底部的“其他问题”,但我可能会研究主要问题。

标签: c# wpf xaml togglebutton expander


【解决方案1】:

首先,考虑将您的 Expander 模板修改为如下所示:

 <Expander>
            <Rectangle Height="500" Width="500" Fill="Red"/>
            <Expander.Template>
                <ControlTemplate TargetType="Expander">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="20"/>
                        </Grid.RowDefinitions>
                        <ContentPresenter Grid.Row="0" x:Name="ContentPresenter"/>
                        <ToggleButton Grid.Row="1" IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsExpanded}"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsExpanded" Value="True">
                            <Setter TargetName="ContentPresenter" Property="Visibility" Value="Visible"/>
                        </Trigger>
                        <Trigger Property="IsExpanded" Value="False">
                            <Setter TargetName="ContentPresenter" Property="Visibility" Value="Collapsed"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Expander.Template>
        </Expander>

我会从上到下解释它是如何工作的,以及为什么它以前不工作。 首先,您需要在扩展器中实际放置一些东西以确保其正常工作 - 我现在在这里放置了一个固定大小的矩形。

接下来,我将第一个 RowDefinition 更改为 auto 而不是 *,因为您希望扩展器在打开时实际展开。 (而不仅仅是将其内容隐藏在一个大的空白区域中)。 Auto 使用的空间与行中内容所需的空间一样多,因此当它折叠时,该大小将为 0,当它展开时,auto 将变为 500 以适应矩形。

我做的第三件事是从 ContentPresenter 中删除您的绑定。碰巧的是,Windows 的内容承载模板(就像在其中可以放置其他东西的任何东西一样)将自动在其模板中查找第一个 ContentPresenter / ItemsPresenter 标记并将内容推入其中。

然而,至于切换按钮(我保持简单并将其保留为标准切换按钮),这个确实需要绑定。 我所做的是将相对源模板绑定到属性“IsExpanded”。 切换按钮有 2 个主要状态:“选中”和“未选中”(真/假),扩展器有 2 个主要状态:“展开”和“折叠”(真/假)。 所以基本上我所做的只是告诉 ToggleButton 与它所在的父级共享其被选中或未选中的真/假状态。

完整的绑定再次是"{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsChecked}",在英文中基本上是说“绑定到相关源,相关源是您在模板中的父级,并且绑定到所述模板;s”IsChecked " 属性。

最后我改变了你的触发器,这些触发器一直在让 ContentPresenter 被隐藏(试图通过减小它所在的 Grid.Row 的大小来压缩它),而是告诉它在扩展器的“IsExpanded”(由于我们的绑定,ToggleButton 的“IsChecked”)设置为 false,而当它们设置为 true 时则相反。

.

至于您的其他问题: 1) ContentSource 用于为 ContentPresenter 提供别名/备用名称,我怀疑您很快就会需要它。我承认,属性名称有点误导。

2) 正如我们在上面看到的,不 - ToggleButton 需要绑定到模板化父级的“IsExpanded”属性才能工作。 如果您要取出按钮,在您创建绑定或在代码中发出指令告诉它打开/关闭之前,扩展器根本无法工作。

【讨论】:

  • 谢谢您,先生,您拯救了我的一天! :)
  • 好的,我测试了你的解决方案 - 现在我面临一个新问题 - 当我在主视图中将一些内容添加到我的自定义控件时,扩展器的 contentpresenter 将扩展边界。跨度>
  • 你能把它的截图和你在主视图中的代码贴出来吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-07
  • 1970-01-01
  • 2021-11-14
  • 2016-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多