C# 如何在动态生成的按钮上更改默认鼠标悬停行为

C# 如何在动态生成的按钮上更改默认鼠标悬停行为,c#,wpf,code-behind,dynamically-generated,mousehover,C#,Wpf,Code Behind,Dynamically Generated,Mousehover,我是WPF的一个相对较新的用户,遇到了一个关于动态按钮生成和按钮默认悬停属性的问题 我目前正在开发一个应用程序,其中在代码隐藏的画布上生成了大量按钮。每个按钮的内容都是由包含Uri字符串的对象数组引用的唯一图像。此数组通过读取包含这些Uri字符串的文件来填充,因此此画布上按钮的数量和位置根据读取的文件而异 在大多数情况下,应用程序运行时画布的外观是预期的,但是在鼠标重叠期间,将鼠标悬停在任何按钮上会将图像替换为默认的蓝色背景 下面是我用来生成按钮的代码示例: exampleButton = ne

我是WPF的一个相对较新的用户,遇到了一个关于动态按钮生成和按钮默认悬停属性的问题

我目前正在开发一个应用程序,其中在代码隐藏的画布上生成了大量按钮。每个按钮的内容都是由包含Uri字符串的对象数组引用的唯一图像。此数组通过读取包含这些Uri字符串的文件来填充,因此此画布上按钮的数量和位置根据读取的文件而异

在大多数情况下,应用程序运行时画布的外观是预期的,但是在鼠标重叠期间,将鼠标悬停在任何按钮上会将图像替换为默认的蓝色背景

下面是我用来生成按钮的代码示例:

exampleButton = new Button { Content = "Name", Width = 50, Height = 65, Background = new ImageBrush(new BitmapImage(new Uri(@object.UriString, UriKind.Relative))) };
exampleButton.Style = exampleStyle;
exampleCanvas.Children.Add(exampleButton);
请理解,我省略了一些与我的问题无关的代码

下面是在代码隐藏中使用的样式示例:

exampleStyle = new Style(typeof(Button));
exampleStyle.Setters.Add(new Setter(Button.ForegroundProperty, Brushes.Transparent));
exampleStyle.Setters.Add(new Setter(Button.BorderBrushProperty, Brushes.Transparent));
exampleButton.Style = (Style)FindResource("MySuperButtonStyle");
除了悬停行为之外,这些因素一起达到了我试图创造的效果

到目前为止,我已经尝试将ControlTemplate重写附加到样式声明中,但不确定如何将其从XAML转换为C#代码。我也尝试过创建和绑定在XAML中创建的按钮模板,但是我没有成功地找到适用于我的情况的解释或教程

任何通过代码隐藏来实现这一点的帮助都将不胜感激。当然,如果我真的非传统地这样做,并且有一种更标准的做事方式,我会洗耳恭听

编辑: 这是我用来声明动态生成的按钮使用的样式的XAML

<Style x:Key="MySuperButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="OverridesDefaultStyle" Value="True" />
        <Setter Property="Width" Value="50" />
        <Setter Property="Height" Value="65" />
        <Setter Property="Foreground" Value="Transparent" />
        <Setter Property="BorderBrush" Value="Black" />
        <Setter Property="BorderThickness" Value="1" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}">
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="BorderBrush" Value="Black"/>
            </Trigger>
        </Style.Triggers>
    </Style>

这是因为默认的
按钮
控件样式有一个触发器,当鼠标悬停在按钮上时,该触发器会更改按钮的
背景
属性。您需要为按钮使用自定义样式:

<Style x:Key="MySuperButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="OverridesDefaultStyle" Value="True" />
    <Setter Property="Width" Value="50" />
    <Setter Property="Height" Value="65" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border Background="{TemplateBinding Background}">
                    <ContentPresenter HorizontalAlignment="Center"
                        VerticalAlignment="Center" />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这里的宽度和高度是使用样式设置的,因此您不再需要在代码中设置这些属性。控件模板已更改,因此它只包含一个
边框
元素,其中包含内容。根本没有触发器,因此当单击或将鼠标悬停在按钮上方时,按钮不会改变其外观

在代码中,您需要做的就是获取对该样式的引用,然后在创建按钮时将该引用指定给
style
属性


话虽如此,在WPF中,您很少需要在代码中创建控件。相反,您应该真正使用MVVM(Model-View-ViewModel)模式和数据绑定。您可能也不应该在代码中创建样式和设置器。

这就成功了,谢谢。如果我真的想加一个触发器,它看起来会像这样吗<代码>当我将其插入样式时,似乎什么都没有发生。您希望将类似的触发器添加到样式的触发器集合,而不是控件模板的触发器集合。换句话说,
我已经实现了您所建议的,并且从我所知道的情况来看,触发器正在按预期触发,但是BorderBrush的属性要么没有实际更改,要么没有反映更改。即使在样式声明中显式地设置它的值也没有任何作用。它是否被某些内容覆盖?@RGMGDD是否可以编辑您的问题以发布样式的XAML?@RGMGDD这是因为您的
BorderThickness
属性在样式中设置,但您尚未将该属性绑定到控件模板中,因此
Border
元素使用其默认厚度为零。颜色会随着触发而改变,但你看不到,因为厚度实际上使边框不可见。只需在模板内设置边框厚度,如下所示:
BorderThickness=“{TemplateBinding BorderThickness}”