自定义按钮,可见性不一致

时间:2012-06-13 18:45:56

标签: wpf xaml custom-controls

下面定义的EditCommandButton样式显示奇怪的行为;它仅显示定义的最后一个实例(在下面的头像标签旁边)。

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

我最终希望按钮在请求之前不可见,这就是为什么你会看到触发器的原因。但直到我弄清楚这一点,我才能看到默认的可见性。

有人可以解释这种行为并提供修复吗?

干杯,
Berryl

设计视图

enter image description here

运行时视图

enter image description here

按钮样式

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

编辑Rachel

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

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

enter image description here

FIX

<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 Precedence - 这是Rachel的回答,尽管她的回答。但我发现唯一有效的修复方法是使用IsMouseOver的两个触发器设置可见性,如图所示。
  2. 只有网格中的最后一项显示任何内容! - 这个对我来说没有任何意义,但将之前在TextBlock内容中的属性移动到样式上的Setters修复了这个。

1 个答案:

答案 0 :(得分:2)

<Tag>中定义的Dependencey属性的优先级高于触发器中定义的项,因此将始终覆盖它们。

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

<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可以包含箭头{{1} }

修复方法是使用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> 的错误。这通常是在这种情况下发生的事情(有关更多详细信息,请参阅我的帖子here