WPF按钮背景问题

3

我有一个包含25个按钮的网格控件(该网格仅包含按钮)。每个按钮都设置了相同的图像,如下所示:

     ImageBrush brush = new ImageBrush();
     BitmapImage bitmap = new BitmapImage();
     bitmap.BeginInit();
     bitmap.UriSource = new Uri(@"pack://application:,,,/Images/notexplored.jpg", UriKind.RelativeOrAbsolute);
     bitmap.EndInit();
     brush.ImageSource = bitmap;

     foreach (UIElement uie in myGrid.Children)
     {
        var temp = uie as Button;
        temp.Background = brush;
     }

我的问题是,当我悬停在按钮上时,会出现这种情况(这是一个短视频,展示了问题):https://www.dropbox.com/s/jb8fb29lrpimue5/ButtonIssue.avi。如何纠正这个问题?将图像应用为按钮的背景后,如果我在按钮上悬停,我不想看到默认的按钮背景(外观),而是应用的图像。请帮忙解决。

顺便说一下,你现在有足够的声望可以点赞了。 ;) - Athari
4个回答

3

为了方便重现示例,我在此将“StackPanel”作为容器。如果您不需要动态设置图像,则希望按照下面所示应用样式可以让按钮的外观和感觉符合您的期望,同时仍然允许您与事件等一样使用典型的WPF按钮。

<StackPanel x:Name="sp">
        <StackPanel.Resources>
            <Style TargetType="{x:Type Button}" x:Key="btnWithImageBgStyle">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Border CornerRadius="5" BorderBrush="{TemplateBinding BorderBrush}" >
                                <Border.Background>
                                    <ImageBrush ImageSource="pack://application:,,,/Tulip.jpg"/>
                                </Border.Background>
                                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </StackPanel.Resources>
        <Button x:Name="btn1" Width="100" Height="50" Content="Button1!" Style="{StaticResource btnWithImageBgStyle}" Click="btn1_Click"/>
        <Button x:Name="btn2" Width="100" Height="50" Content="Button2!" Style="{StaticResource btnWithImageBgStyle}"/>
        <Button x:Name="btn3" Width="100" Height="50" Content="Button3!" Style="{StaticResource btnWithImageBgStyle}"/>

1
不要设置背景,只需将一个新的图像作为按钮的内容添加。以下是一个小例子:
var b = new Button();

var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = new Uri(@"pack://application:,,,/floor.png", UriKind.RelativeOrAbsolute);
bitmap.EndInit();

var img = new Image {Source = bitmap};

b.Content = img;

我已将内容设置为图像,但现在出现了另一个错误:指定的元素已经是另一个元素的逻辑子元素。请先断开连接。 - Rock3rRullz
我使用了以下代码来设置图像: Image image = new Image(); BitmapImage bi = new BitmapImage(); bi.BeginInit(); bi.UriSource = new Uri(@"pack://application:,,,/Images/notexplored.jpg", UriKind.RelativeOrAbsolute); bi.EndInit(); image.Source = bi; - Rock3rRullz
如果我将内容设置为位图,则按钮文本将显示来自Uri的字符串。如果我将内容设置为img,则会收到与上述相同的错误。 - Rock3rRullz
抱歉,示例中有一个小错误,现已修复。要删除悬停效果,请按照此教程操作:http://mark-dot-net.blogspot.dk/2007/07/creating-custom-wpf-button-template-in.html - dsfgsho
仍然不行,我的意思是当我将内容设置为图像时出现了断开连接的错误。 - Rock3rRullz

1

您需要更改按钮的控件模板,以便它不再响应MouseOver事件。最简单的解决方案可能是这样的:

<Window.Resources>
    <Style TargetType="{x:Type Button}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <ContentPresenter />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

这是一个隐式样式,适用于窗口内的每个按钮。在控件模板中,您可以更改按钮的外观以及其状态更改时的行为(例如,当鼠标悬停在按钮上时)。
通常,控件模板会包含更多的代码,但在此示例中,您只想要一个显示某些内容的按钮,省略所有其他行为方面的内容(例如鼠标悬停或单击时的效果)。您可以在MSDN上查看WPF中按钮的默认模板: http://msdn.microsoft.com/en-us/library/ms753328.aspx 我强烈建议您了解WPF中的样式和模板。这是一个很好的入门指南: http://msdn.microsoft.com/en-us/library/ms745683.aspx 如果您有问题,请随时留言。

“Grid” 是多余的。而且在这种微不足道的情况下,我看不出将模板单独放置而不是直接放入 “Setter.Value” 的原因。 - Athari
确实。我只是在午餐时间快速使用Blend生成了代码,请原谅我。 - feO2x

1

如果你只需要显示一个图像并响应点击,那么使用按钮就过于复杂了。你可以只使用 ContentControl


如果他想要对“Click”事件做出反应,我认为按钮是完全可以的。 - feO2x
我想使用点击事件来确定我点击的是哪个单元格,这就是我使用网格的原因,并且每个按钮都定义为:<Button Grid.Column="3" Grid.Row="0" Click="ButtonBase_OnClick"/>。 - Rock3rRullz
MouseDown或MouseUp事件就足够了。如果没有计划进行键盘访问,行为并没有太大的区别。 - Athari
如果我使用以下代码中的图像代替按钮,为什么鼠标左键按下事件无法执行?<Image Grid.Column="0" Grid.Row="0" MouseLeftButtonDown="UIElement_OnMouseLeftButtonDown"/> - Rock3rRullz
@Rock3rRullz 只有在源图片加载完成后,图像才可点击。 - Athari

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接