【问题标题】:ContentPresenter loosing it data binding after triggers invoked more than twiceContentPresenter 在触发器调用两次以上后失去数据绑定
【发布时间】:2020-01-05 08:00:13
【问题描述】:

我创建了一个扩展按钮,该按钮具有两种不同的边框样式,由 XAML 中的触发器调用。两者共享相同的 contentpesenter,但在更改边框样式两次以上后 contentpresenter 中的内容无法显示。

下面是整个项目的链接,其中包含一个演示问题的测试床应用程序,我认为问题出在下面的 XAML 中,但我看不出它为什么会中断:

Sample Button App

       <Style.Resources>
        <ContentPresenter x:Key="ButtonContent" Margin="5" HorizontalAlignment="Center" 
               Content="{Binding Content}"/>
    </Style.Resources>


    <Setter Property="Template">
         <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid Margin="{Binding KeyMargin}">
                    <Grid Visibility="{Binding RectangleVisibility}">
                        <Grid.OpacityMask>
                            <VisualBrush Visual="{Binding ElementName=rectBorder}" />
                        </Grid.OpacityMask>
                        <Border x:Name="rectBorder" 
                            CornerRadius="{Binding BorderCorners}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            Background="{TemplateBinding Background}"   
                            BorderThickness="{Binding BorderThickness}"/>
                        <Viewbox Stretch="Fill" 
                            StretchDirection="Both">
                            <ContentControl Content="{StaticResource ButtonContent}"/>
                        </Viewbox>
                    </Grid>

                    <Grid Visibility="{Binding EllipseVisibility}">
                        <Ellipse Stroke="{TemplateBinding BorderBrush}"
                            StrokeThickness="{Binding BorderThickness}"
                            Fill="{TemplateBinding Background}">
                        </Ellipse>
                        <Viewbox Stretch="Fill"
                            StretchDirection="Both">
                            <ContentControl Content="{StaticResource ButtonContent}"/>
                        </Viewbox>
                    </Grid>

                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

【问题讨论】:

    标签: wpf xaml


    【解决方案1】:

    问题很可能是你不能在可视化树中的多个位置拥有相同的元素(在本例中为 ContentPresenter),并且它最终出现的两个网格之一是未定义的,即实现WPF 的原型。

    要复制元素,这可能有效:

    <ContentControl Content="{TemplateBinding Content}"/>
    

    或者在你的情况下

    <ContentControl Content="{TemplateBinding Content}" Margin="5" HorizontalAlignment="Center"/>
    

    而不是静态资源。 &lt;ContentPresenter/&gt; 语法几乎是一个优化的快捷方式(或者您可以在资源上设置 x:Shared="False",但是据我所知,将 ContentPresenter 作为静态资源是如何的打算使用)

    如果 Button 内容本身是一个 UIElement,它将在可视化树中直接使用,即两次,这也不起作用。更好的解决方案是在控件模板中只包含一次内容并更改其周围的视觉外观,例如,使用触发器来设置 Grid 的 OpacityMask。

    另外一点是,您的控件模板与使用 Button 的位置紧密绑定,直接绑定到当前数据上下文,这降低了它的可重用性。一些简单的解决方法是使用 TemplateBinding 而不是 Binding 分别用于 BorderThickness Margin(而不是 KeyMargin),因为这些是 Button 的现有属性。

    为了更好的可重用性和更简洁的代码,您应该考虑创建一个从 Button 派生的自定义控件,该控件具有 BorderCorners 的依赖属性、所需的视觉状态(椭圆与矩形)等。您可能还想使用触发器来获取鼠标 -按钮等的效果。玩得开心控制模板!

    【讨论】:

    • 非常感谢 Magnus 的精彩提示。
    猜你喜欢
    • 2015-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-04
    • 2018-02-02
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    相关资源
    最近更新 更多