如何使 WPF 按钮看起来像一个链接?

Posted

技术标签:

【中文标题】如何使 WPF 按钮看起来像一个链接?【英文标题】:How do I make a WPF button look like a link? 【发布时间】:2011-07-04 14:05:11 【问题描述】:

我想在 WPF 中使用样式类似于链接的按钮。 Microsoft 在其 Windows 对话框中这样做(似乎不一致)。

它们看起来像蓝色文本。并在鼠标悬停时更改颜色和下划线。

示例:

我让它工作了。 (感谢Christian、Anderson Imes 和MichaC)但是,我必须在按钮中添加TextBlock

如何改进我的风格——让它在我的 Button 中不需要 TextBlock 的情况下工作?

使用 XAML

<Button Style="StaticResource HyperlinkLikeButton">
    <TextBlock>Edit</TextBlock>
</Button>

样式 XAML

<Style x:Key="HyperlinkLikeButton" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <ContentPresenter />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Foreground" Value="DynamicResource x:Static SystemColors.HotTrackBrushKey" />
    <Setter Property="Cursor" Value="Hand" />
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="true">
            <Setter Property="Foreground" Value="DynamicResource x:Static SystemColors.HighlightBrushKey" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <ControlTemplate.Resources>
                            <Style TargetType="x:Type TextBlock">
                                <Setter Property="TextDecorations" Value="Underline" />
                            </Style>
                        </ControlTemplate.Resources>
                        <ContentPresenter />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Trigger>
    </Style.Triggers>
</Style>

【问题讨论】:

你的按钮在被点击时实际上在做什么?只是导航? 【参考方案1】:

你知道有一个Hyperlink 类/标签吗?它看起来像一个超链接,也可以用作按钮(可以使用 URI 和/或命令和/或单击事件)。

编辑:

使用示例:

<TextBlock>                                
    <Hyperlink Command="Binding SomeCommand, ElementName=window" CommandParameter="Binding">Link
    </Hyperlink>
</TextBlock>

【讨论】:

HyperlinkFrameworkContentElement,而不是 FrameworkElement。 Silverlight 有一个符合要求的HyperlinkButton,但可惜 WPF 没有。 叹息 +1:这就是我的想法 - 可以指定页面 URI,不确定点击事件。 @Kent Boogaart:然后呢?只需将链接包装在 TextBlock 中即可。我很乐意到处使用这样的超链接。这肯定比扭动按钮看起来像超链接更容易(也更有意义)。 如何解决 OP 的问题?现在他需要在其中指定TextBlockHyperlink 只需实现一个自定义控件。这似乎有点过头了,但肯定不会比重新设置按钮的控件模板更过分。【参考方案2】:

我认为问题在于按钮是一个内容控件,但链接样式仅适用于作为内容的文本。这就是您拥有的代码以这种方式设计的原因。我认为我们可以通过指定文本块而不是内容呈现器来在控件模板中工作,但是绑定到它的属性是什么?所以我的建议是:subclass 按钮并声明一个字符串类型的依赖属性,并使用该属性绑定 ControlTemplate 中的文本。

【讨论】:

【参考方案3】:

除非我遗漏了一些东西,否则如果你应用的是内联样式而不是全局样式,你就不能摆脱TextBlock 的样式吗?例如:

<Style x:Key="LinkButton" TargetType="TextBlock">            
    <Setter Property="Cursor" Value="Hand" />
    <Setter Property="Margin" Value="0,0,10,0" />
    <Setter Property="TextDecorations" Value="Underline" />
    <Setter Property="Foreground" Value="DynamicResource x:Static SystemColors.HotTrackBrushKey" />
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="true">
            <Setter Property="Foreground" Value="DynamicResource x:Static SystemColors.HighlightBrushKey" />                 
        </Trigger>
    </Style.Triggers>
</Style>

所以:

<TextBlock Style="StaticResource LinkButton">Edit</TextBlock>

要启用点击,只需使用MouseUp 事件。

【讨论】:

【参考方案4】:

使用以下样式或模板不需要您使用 TextBlock 元素:

  <ControlTemplate x:Key="HyperlinkLikeButtonTemplate" TargetType="x:Type Button">
      <TextBlock x:Name="innerText" Foreground="DynamicResource x:Static SystemColors.HotTrackBrushKey" Cursor="Hand" >
        <ContentPresenter />
      </TextBlock>
    <ControlTemplate.Triggers>
      <Trigger Property="Button.IsMouseOver" Value="true">
        <Setter TargetName="innerText" Property="Foreground" Value="DynamicResource x:Static SystemColors.HighlightBrushKey" />
        <Setter TargetName="innerText" Property="TextDecorations" Value="Underline" />
      </Trigger>
    </ControlTemplate.Triggers>
  </ControlTemplate>

  <Style x:Key="HyperlinkLikeButton" TargetType="x:Type Button">
    <Setter Property="Template" Value="StaticResource HyperlinkLikeButtonTemplate" />
  </Style> 

使用 XAML

<Button Style="StaticResource HyperlinkLikeButton" Content="Edit" />

<Button Style="StaticResource HyperlinkLikeButton">
    Edit
</Button>

也可以直接使用模板

<Button Template="StaticResource HyperlinkLikeButtonTemplate" Content="Edit" />

【讨论】:

您的解决方案很棒,我唯一的修改是将整个 ControlTemplate 块放在样式“模板”属性中 - 这样就不需要为 ControlTemplate 命名键并且更易于阅读。 【参考方案5】:

我参加聚会有点晚了,但是...

IMO 最简单、最干净的方法:

<Style x:Key="HyperLinkButtonStyle" TargetType="Button">
    <Setter Property="Focusable" Value="False" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <TextBlock>
                    <Hyperlink>
                        <Run Text="TemplateBinding Content" />
                    </Hyperlink>
                </TextBlock>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
忠实,不模仿:我们只使用Hyperlink 本身 尊重:保留重点,这是一个重要的方面

【讨论】:

为了真正起作用,HyperLink 的 Command 和 CommandParameter 需要绑定到按钮上的原始属性。

以上是关于如何使 WPF 按钮看起来像一个链接?的主要内容,如果未能解决你的问题,请参考以下文章

如何使 html 链接看起来像一个按钮?

禁用 WPF 窗口标题栏中的关闭按钮 (C#)

WPF:如何使 RichTextBox 看起来像 TextBlock?

通过按钮进行 WPF 导航

如何使控件扩展通过控件绑定或与其他控件重叠?

如何使用引导程序使表格内的单选按钮看起来像一个按钮?