【问题标题】:WPF - Why is my buttons content moving separately from the button itself?WPF - 为什么我的按钮内容与按钮本身分开移动?
【发布时间】:2009-07-01 15:15:42
【问题描述】:

我在正在编写的 WPF 应用程序中创建了一个 TabControl。我重新设计了 TabItem 模板,以便在每个选项卡标题上都有一个按钮来关闭它。到目前为止,一切都很好。

我决定我现在想要闪亮的圆形按钮,而不是默认的方形丑陋的东西。另外,我想使用图像作为按钮内容,而不是简单地将内容设置为“X”。

我的 XAML 样式/模板:

<Style TargetType="{x:Type Button}" x:Key="EllipseButtonStyle">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Grid>
                     <Ellipse Fill="{TemplateBinding Background}"
                         Stroke="{TemplateBinding BorderBrush}"
                         StrokeThickness="{TemplateBinding BorderThickness}"
                         Width="{TemplateBinding Width}"
                         Height="{TemplateBinding Height}"/>
                     <ContentPresenter HorizontalAlignment="Center" 
                         VerticalAlignment="Center"
                         Content="{TemplateBinding Button.Content}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<DataTemplate x:Key="ClosableTabItemTemplate">
    <DockPanel MinWidth="120" Margin="0,0,0,0">
        <ContentPresenter 
            Content="{Binding Path=DisplayName}" 
            VerticalAlignment="Center"
            HorizontalAlignment="Left"/>
        <Button
            Command="{Binding Path=UnSubscribeApplicationCommand}"
            CommandParameter="{Binding Path=DisplayName}"
            BorderBrush="Black"
            BorderThickness="2"
            VerticalContentAlignment="Center"
            VerticalAlignment="Center"
            HorizontalAlignment="Right"
            DockPanel.Dock="Right"
            Width="16" Height="16">
            <Image Source="closeicon.bmp" Height="8" Width="8" 
                VerticalAlignment="Center" HorizontalAlignment="Center"/>
                <Button.Style>
                    <Style TargetType="{x:Type Button}" 
                        BasedOn="{StaticResource EllipseButtonStyle}">
                        <Setter Property="Background"
                            Value="{StaticResource CloseOffButtonBrush}"/>
                        <Style.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" Value="{StaticResource CloseOnButtonBrush}"/>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </Button.Style>
            </Button>
        </DockPanel>
    </DataTemplate>

然而,使用上面的代码,选定的选项卡内容(以及背景)似乎向上移动,因为我认为 TabItems 内容由于它被选中而向上移动。那么,为什么椭圆没有随着其他内容移动?有人知道这里发生了什么吗?

【问题讨论】:

  • 为什么要使用 DataTemplate?你能发布更多代码吗?
  • 我刚刚解决了这个问题 - 你说得对,它不应该是一个 DataTemplate。稍后我会发布我的解决方案。

标签: wpf button uibutton tabcontrol


【解决方案1】:

抱歉延迟响应 - 我最终通过在 this blogpost 中发布的模板之后建模我的 TabItem 模板来解决问题。我认为问题浮出水面是因为我的 TabItem 模板被定义为 DataTemplate,而不是应有的 ControlTemplate。这是新模板:

<ControlTemplate x:Key="ClosableTabItemTemplate" TargetType="TabItem">
    <Grid SnapsToDevicePixels="true">
        <Border x:Name="Bd" Background="{StaticResource TabItemUnselectedBrush}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,0" >
            <DockPanel x:Name="ContentPanel">
                <Button Command="{Binding Path=UnSubscribeApplicationCommand}" BorderBrush="Black" HorizontalAlignment="Center" Margin="3,0,3,0" VerticalAlignment="Center" Width="16" Height="16" DockPanel.Dock="Right" ToolTip="Close Tab">
                    <Button.Content>
                        <Image Source="pack://application:,,,/Resources/Close.png" Height="8" Width="8" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                    </Button.Content>
                    <Button.Style>
                        <Style TargetType="{x:Type Button}" BasedOn="{StaticResource EllipseButtonStyle}">
                            <Setter Property="Background" Value="{StaticResource CloseOffButtonBrush}"/>
                            <Style.Triggers>
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter Property="Background" Value="{StaticResource CloseOnButtonBrush}"/>
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </Button.Style>
                </Button>
                <ContentPresenter x:Name="Content" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{Binding Path=DisplayName}" RecognizesAccessKey="True" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="{TemplateBinding Padding}"/>
            </DockPanel>
        </Border>
    </Grid>

    <!-- bunch of ControlTemplate triggers to style the TabItem background color/position -->

</ControlTemplate>

【讨论】:

    【解决方案2】:

    每当我在 DockPanel 中有控件时,如果我明确附加 DockPanel.Dock 的控件之一出现在我想要占据填充部分的元素之后,它似乎总是会播放。虽然我不知道这是否会回答您的问题,但请在您的 ClosableTabItemTemplate DataTemplate 中尝试此操作:

    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"/>
      </Grid.ColumnDefinitions>
    
      <ContentPresenter Grid.Column="0"/>
    
      <Button Grid.Column="1"/>
    </Grid>
    

    【讨论】:

    • 试过了,但仍然收到相同的行为。还有其他想法吗?
    • 实际上,我能看出你和我在做这件事的方式上只有几处不同。 1)您是否设置了 TabItem 的 HeaderTemplate? 2) 在 ClosableTabItemTemplate 的根项中打开 SnapsToDevicePixels,并让 ContentPresent 从 TemplateBinding 设置其 SnapsToDevicePixels。 3) 我们的关闭按钮样式使用的是 DynamicResource。 4) 在 TabItem 的 IsSelected 触发器上,我们将 Panel.ZIndex 设置为 1。希望这会有所帮助...如果我有更多代码,我可能会解决它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-22
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    相关资源
    最近更新 更多