【问题标题】:custom button with inconsistent visibility可见性不一致的自定义按钮
【发布时间】:2012-06-13 18:45:55
【问题描述】:

下面定义的 EditCommandButton 样式表现出奇怪的行为;它只显示定义的最后一个实例(在下面的 Avatar 标签旁边)。

我尝试制作样式 x:Shared="true" 并使用 DynamicResource 但结果相同。

我最终确实希望按钮在请求之前不可见,这就是为什么您会看到触发该按钮的原因。但在我弄清楚这一点之前,我只有默认可见性可见。

有人可以解释这种行为并提供解决方法吗?

干杯,
浆果

设计视图

运行时视图

按钮样式

<Style x:Key="EditCommandButtonStyle" TargetType="{x:Type Button}" >
    <Setter Property="Content">
        <Setter.Value>
            <TextBlock Text="a" Foreground="Navy" FontWeight="Bold" FontFamily="Wingdings 3" FontSize="24" Width="30"/>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border x:Name="theBorder" Background="Transparent" CornerRadius="4">
                    <ContentPresenter x:Name="theContent" Visibility="Visible" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="theContent" Property="Visibility" Value="Visible"/>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter TargetName="theContent" Property="Visibility" Value="Visible"/>
                        <Setter TargetName="theBorder" Property="Background" Value="Orange"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Command" Value="{Binding SelectedSatelliteVm.EditCommand}"/>
</Style>

用法

<DataTemplate x:Key="PersonInfoEditingControlTemplate">

    <Grid>

        ...

        <Label Grid.Column="0" Grid.Row="0" ... />
        <Button Style="{StaticResource EditCommandButtonStyle}" Grid.Column="1" Grid.Row="0"/>
        <TextBlock .../>

        <Label Grid.Column="0" Grid.Row="1" ... />
        <Button Style="{StaticResource EditCommandButtonStyle}" Grid.Column="1" Grid.Row="1"/>
        <TextBlock .../>

        <TextBlock  Grid.Column="0" Grid.Row="2"  .../>
        <Button Style="{StaticResource EditCommandButtonStyle}" Grid.Column="1" Grid.Row="2"/>
        <Image Grid.Column="2" Grid.Row="2" ... />

    </Grid>

</DataTemplate>

为瑞秋编辑

看,妈,没有触发器!不过只有最后一个按钮显示箭头...

<Style x:Key="TestCommandButtonStyle" TargetType="{x:Type Button}" >
    <Setter Property="Content">
        <Setter.Value>
            <TextBlock Text="a" Foreground="Navy" FontWeight="Bold" FontFamily="Wingdings 3" FontSize="24" Width="30"/>
        </Setter.Value>
    </Setter>
    <Setter Property="Command" Value="{Binding SelectedSatelliteVm.EditCommand}"/>
</Style>

修复

<Style x:Key="EditCommandButtonStyle" TargetType="{x:Type Button}" >
    <Setter Property="Content" Value="a" />
    <Setter Property="Foreground" Value="Navy" />
    <Setter Property="FontFamily" Value="Wingdings 3" />
    <Setter Property="FontWeight" Value="Bold" />
    <Setter Property="FontSize" Value="18" />
    <Setter Property="Width" Value="30" />
    <Setter Property="Height" Value="Auto" />
    <Setter Property="Command" Value="{Binding SelectedSatelliteVm.EditCommand}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border x:Name="theBorder" CornerRadius="4">
                    <ContentPresenter x:Name="theContent" VerticalAlignment="Center" HorizontalAlignment="Center" />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="False">
                        <Setter TargetName="theContent" Property="Visibility" Value="Hidden"/>
                        <Setter TargetName="theBorder" Property="Background" Value="Transparent"/>
                    </Trigger>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="theContent" Property="Visibility" Value="Visible"/>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter TargetName="theContent" Property="Visibility" Value="Visible"/>
                        <Setter TargetName="theBorder" Property="Background" Value="Orange"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

原来写的样式实际上有两个问题,都被上面的样式修复了。 (固定我的意思是它按预期工作,而不是它是“正确”的方法!):

  1. DP 优先级 - 这是 Rachel 的回答所要解决的问题,尽管她的回答是。但我发现唯一有效的解决方法是使用 IsMouseOver 的两个触发器设置可见性,如图所示。
  2. 只有网格中的最后一项显示了任何内容! - 这对我来说毫无意义,但是将之前在 TextBlock 内容中的属性移动到样式上的 Setters 可以解决这个问题。

【问题讨论】:

    标签: wpf xaml custom-controls


    【解决方案1】:

    &lt;Tag&gt; 中定义的依赖属性比触发器中定义的项目具有更高的优先级,因此将始终覆盖它们。

    例如,在这种情况下,无论触发器是什么,按钮的Visibility 将始终为Collapsed,因为该属性是在&lt;Button&gt; 标记中定义的

    <Button Visibility="Collapsed">
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Style.Triggers>
                    <DataTrigger Property="{Binding SomeValue}">
                        <Setter Property="Visibility" Value="Visible" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>
    

    要使此触发器起作用,请将 Visibility 属性移动到样式设置器,它的优先级低于样式触发器,因此触发的值将覆盖它

    <Button>
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="Visibility" Value="Collapsed" />
                <Style.Triggers>
                    <DataTrigger Property="{Binding SomeValue}">
                        <Setter Property="Visibility" Value="Visible" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>
    

    有关详细信息,请参阅 MSDN 的 Dependency Property Precedence List

    编辑

    至于你的第二个问题,内容只显示一次,我怀疑这是因为你的风格绑定了Content,而不是ContentTemplate

    WPF正在创建TextBlock箭头的单个实例,并且一个控件只能有一个父级,所以应用样式后,只有一个Button可以包含箭头TextBlock

    解决方法是使用ContentTemplate 属性而不是Content 属性。

    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <TextBlock Text="a" Foreground="Navy" FontWeight="Bold" FontFamily="Wingdings 3" FontSize="24" Width="30"/>
            </DataTemplate>
        </Setter.Value>
    </Setter>
    

    老实说,我很惊讶它没有给你一个关于 Specified element is already the logical child of another element 的错误。在这种情况下通常会发生这种情况(有关详细信息,请参阅我的帖子 here

    【讨论】:

    • 肯定有用的信息,但这并不能解释或解决我原来的问题。请参阅最后的编辑。干杯
    • @Berryl 你在theContent 上有一个Visibility 触发器
    • 否,最后一次编辑的样式(“TestCommandButtonStyle”)没有触发器和可见性属性设置。这是一个奇怪的...
    • 足够接近,但其他任何卡住的人的完整修复在原始帖子的末尾。干杯
    • @Berryl 我今天早上重新阅读了您的问题并更新了我的答案,以包括您的第二个问题的可能原因
    猜你喜欢
    • 2013-06-07
    • 1970-01-01
    • 2019-08-19
    • 2012-06-15
    • 1970-01-01
    • 2013-04-24
    • 1970-01-01
    • 2017-02-09
    • 1970-01-01
    相关资源
    最近更新 更多