如何更改动态生成按钮上的默认鼠标悬停行为
How to change default mouse hover behavior on dynamically generated buttons
我是 WPF 的新用户,运行 遇到了有关动态按钮生成和按钮的默认悬停属性的问题。
我目前正在开发一个应用程序,其中在后台代码中的 Canvas 上生成了大量按钮。每个按钮的内容都是由包含 Uri 字符串的对象数组引用的唯一图像。该数组是通过读取包含这些 Uri 字符串的文件来填充的,因此此 canvas 上按钮的数量和位置因正在读取的文件而异。
在大多数情况下,当应用程序 运行s 时 Canvas 的外观是预期的,但是将鼠标悬停在任何按钮上会将图像替换为默认的蓝色背景鼠标重叠的持续时间。
这是我用来生成按钮的代码示例:
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));
这些共同实现了我试图创建的效果,禁止悬停行为。
到目前为止,我已尝试将 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>
使用此调用在后面的代码中分配样式:
exampleButton.Style = (Style)FindResource("MySuperButtonStyle");
这是因为默认的 Button
控件样式有一个触发器,当鼠标悬停在按钮上时,它会更改按钮的 Background
属性。您需要为按钮使用自定义样式:
<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>
这里的宽度和高度是使用样式设置的,因此您不再需要在代码中设置这些属性。控件模板已更改,因此它仅包含一个包含内容的 Border
元素。根本没有触发器,因此单击或悬停时按钮不会改变其外观。
在您的代码中,您需要做的就是获得对此样式的引用,然后在创建按钮时将其分配给 Style
属性。
话虽如此,在 WPF 中您很少需要在代码中创建控件。相反,您应该真正使用 MVVM (Model-View-ViewModel) 模式和数据绑定。您可能也不应该在代码中创建样式和设置器。
我是 WPF 的新用户,运行 遇到了有关动态按钮生成和按钮的默认悬停属性的问题。
我目前正在开发一个应用程序,其中在后台代码中的 Canvas 上生成了大量按钮。每个按钮的内容都是由包含 Uri 字符串的对象数组引用的唯一图像。该数组是通过读取包含这些 Uri 字符串的文件来填充的,因此此 canvas 上按钮的数量和位置因正在读取的文件而异。
在大多数情况下,当应用程序 运行s 时 Canvas 的外观是预期的,但是将鼠标悬停在任何按钮上会将图像替换为默认的蓝色背景鼠标重叠的持续时间。
这是我用来生成按钮的代码示例:
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));
这些共同实现了我试图创建的效果,禁止悬停行为。
到目前为止,我已尝试将 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>
使用此调用在后面的代码中分配样式:
exampleButton.Style = (Style)FindResource("MySuperButtonStyle");
这是因为默认的 Button
控件样式有一个触发器,当鼠标悬停在按钮上时,它会更改按钮的 Background
属性。您需要为按钮使用自定义样式:
<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>
这里的宽度和高度是使用样式设置的,因此您不再需要在代码中设置这些属性。控件模板已更改,因此它仅包含一个包含内容的 Border
元素。根本没有触发器,因此单击或悬停时按钮不会改变其外观。
在您的代码中,您需要做的就是获得对此样式的引用,然后在创建按钮时将其分配给 Style
属性。
话虽如此,在 WPF 中您很少需要在代码中创建控件。相反,您应该真正使用 MVVM (Model-View-ViewModel) 模式和数据绑定。您可能也不应该在代码中创建样式和设置器。