WPF - 为什么我的按钮内容与按钮本身分开移动?

发布于 2024-07-25 20:45:58 字数 2813 浏览 1 评论 0原文

我在我正在编写的 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 内容由于被选择而向上移动。 那么,为什么椭圆不随其他内容移动呢? 有人知道这里发生了什么事吗?

I have created a TabControl in a WPF application I'm writing. I re-templated TabItem so that I could have a button on each tab header to close it. So far, all is well and good.

I decided that I now wanted shiny round buttons instead of the default square ugly things. Also, I wanted to use an image as my buttons content instead of simply setting the content to "X".

My XAML styles/templates:

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

With the above code in place, however, a selected tabs content (and the background as well) seems to shift upwards because of what I assume is the TabItems content moving upwards due to it being selected. Why, then, is the ellipse not shifting with the other content? Anyone have any idea what is going on here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

始终不够 2024-08-01 20:45:58

抱歉回复延迟 - 我最终通过在 此博文。 我相信问题的出现是因为我的 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>

Sorry for the delayed response - I ended up solving the issue by modeling my TabItem template after the one posted in this blogpost. I believe the issue surfaced due to the fact that my TabItem template was being defined as a DataTemplate, not as a ControlTemplate as it should have been. Here is the new template:

<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>
丶情人眼里出诗心の 2024-08-01 20:45:58

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

<Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="Auto"/>
  </Grid.ColumnDefinitions>

  <ContentPresenter Grid.Column="0"/>

  <Button Grid.Column="1"/>
</Grid>

Whenever I have controls inside a DockPanel, it always seems to play up if one of the controls I've explicitly attached DockPanel.Dock to comes AFTER the element I want to take up the fill portion. While I don't know if this will answer your question, try this instead in your ClosableTabItemTemplate DataTemplate:

<Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="Auto"/>
  </Grid.ColumnDefinitions>

  <ContentPresenter Grid.Column="0"/>

  <Button Grid.Column="1"/>
</Grid>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文