前言
在WPF(Windows Presentation Foundation)中设置按钮(Button)涉及到多种属性和功能。
以下是一些常见的设置方法和示例:
设置按钮文本和点击事件
1
| <Button Content="Click Me" Click="ButtonClickHandler" />
|
其中,Content属性用于设置按钮的文本显示,“Click Me”是按钮显示的文本内容。
Click属性是按钮的点击事件,ButtonClickHandler是处理点击事件的方法名。
设置按钮样式和外观
WPF允许通过样式(Style)来自定义按钮的外观。例如,可以在应用程序的资源文件中定义按钮样式:
1 2 3 4 5 6 7 8 9 10 11
| <Window.Resources> <Style TargetType="Button" x:Key="CustomButtonStyle"> <Setter Property="Background" Value="LightBlue"/> <Setter Property="Foreground" Value="Black"/> <Setter Property="FontFamily" Value="Arial"/> <Setter Property="FontSize" Value="14"/> <Setter Property="Padding" Value="10"/> </Style> </Window.Resources>
<Button Content="Styled Button" Style="{StaticResource CustomButtonStyle}" Click="ButtonClickHandler" />
|
定义了一个名为CustomButtonStyle的样式,设置了按钮的背景、前景(文本颜色)、字体等属性。然后,通过Style属性将这个样式应用到按钮上。
设置按钮图标
可以通过WPF的Content属性来设置按钮的内容,这不仅限于文本,还可以是其他元素,比如图标。
1 2 3 4 5 6
| <Button Click="ButtonClickHandler"> <StackPanel Orientation="Horizontal"> <Image Source="/Images/icon.png" Width="20" Height="20"/> <TextBlock Margin="5,0,0,0" Text="Button with Icon"/> </StackPanel> </Button>
|
在这个示例中,按钮的内容是一个StackPanel,包含一个图像和一个文本块,从而实现了带图标的按钮。
动态设置按钮属性
除了静态设置外,还可以在代码中动态设置按钮的属性。
例如,在代码中修改按钮的文本或样式:
1 2 3 4 5 6 7
| myButton.Content = "New Text";
Style newStyle = new Style(typeof(Button)); newStyle.Setters.Add(new Setter(Button.BackgroundProperty, Brushes.Green)); myButton.Style = newStyle;
|
组件内设置
1 2 3 4 5 6 7 8 9 10 11 12
| <Button> <Button.Style> <Style TargetType="Button"> <Setter Property="Foreground" Value="White" /> <Style.Triggers> <DataTrigger Binding="{Binding Selected}" Value="true"> <Setter Property="Foreground" Value="#ffffff" /> </DataTrigger> </Style.Triggers> </Style> </Button.Style> </Button>
|
样式触发器和模板触发器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| <Style x:Key="ExitBtn" TargetType="Button"> <Setter Property="BorderThickness" Value="0" /> <Setter Property="Background" Value="#F0F6FC" /> <Setter Property="Foreground" Value="#253A70" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <Border Width="75" Height="88" Background="{TemplateBinding Background}"> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <Image x:Name="MImg" Width="30" Margin="0,10,0,0" HorizontalAlignment="Center" Source="/Images/Blackboard2/class_7un.png" /> <TextBlock Margin="0,8,0,8" HorizontalAlignment="Center" FontSize="16" Foreground="{TemplateBinding Foreground}" Text="退出" /> </StackPanel> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="MImg" Property="Source" Value="/Images/Blackboard2/class_7s.png" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="#339DFF" /> <Setter Property="Foreground" Value="White" /> </Trigger> </Style.Triggers> </Style>
|
注意
Style.Triggers 不能修改自定义模板中的属性。
ControlTemplate.Triggers是可以改模板的属性。
/Resources/StyleButton.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Style x:Key="MyButton" TargetType="{x:Type Button}"> <Setter Property="OverridesDefaultStyle" Value="True" /> <Setter Property="Cursor" Value="Hand" /> <Setter Property="Background" Value="#2D8CF0" /> <Setter Property="Foreground" Value="#ffffff" /> <Setter Property="HorizontalContentAlignment" Value="Center" /> <Setter Property="VerticalContentAlignment" Value="Center" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border Name="border" Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" ClipToBounds="True" CornerRadius="4"> <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Opacity" Value="0.8" /> </Trigger>
<Trigger Property="IsEnabled" Value="False"> <Setter Property="Opacity" Value="0.6" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
|
Button实现圆角很简单只需Button ContentTemplate修改样式模板就可以实现了。
但是这样无法达到复用,比如另一个按钮设计的不需要圆角样式又用的同一套怎么办?
当然可以在把样式复制下然后改一个样式名字修改下样式就可以了。
但是这样两份样式几乎一样,只不过一个圆角一个不是。
所以我们可以通过自定义Button控件给Button新增一个依赖属性完成这个功能。
添加属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| using System.Windows; using System.Windows.Controls;
namespace ColorPicker.Views { internal class ZRoundButton : Button { #region 属性 public static readonly DependencyProperty BorderRadiusProperty = DependencyProperty.Register("BorderRadius", typeof(int), typeof(ZRoundButton), new FrameworkPropertyMetadata());
public int BorderRadius { get { return (int)GetValue(BorderRadiusProperty); } set { SetValue(BorderRadiusProperty, value); } } #endregion 属性 } }
|
定义样式
/Resources/StyleZRoundButton.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:SchoolClient.Views"> <Style x:Key="ZRoundButtonStyle" TargetType="{x:Type local:ZRoundButton}"> <Setter Property="OverridesDefaultStyle" Value="True" /> <Setter Property="Cursor" Value="Hand" /> <Setter Property="FocusVisualStyle" Value="{x:Null}" /> <Setter Property="HorizontalContentAlignment" Value="Center" /> <Setter Property="VerticalContentAlignment" Value="Center" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border Name="border" Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{Binding Path=BorderRadius, RelativeSource={RelativeSource TemplatedParent}}"> <ContentPresenter Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Opacity" Value="0.8" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
|
全局引用
Application中添加引用
1 2 3 4 5 6 7 8 9
| <Application x:Class="SchoolClient.MyApp" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="Wins/Welcome.xaml"> <Application.Resources> <ResourceDictionary Source="pack://application:,,,/Resources/OverwrideDefaultControlStyles.xaml" /> </Application.Resources> </Application>
|
使用
定义好这个属性就可以在控件中使用了
1 2 3 4 5 6 7 8 9 10
| <view:ZRoundButton BorderRadius="23" Width="300" Height="46" HorizontalAlignment="Center" Background="#4597FF" Content="关闭" Cursor="Hand" FontSize="20" Foreground="White"/>
|
其中主要是BorderRadius="5"用来调整圆角。
我们再看看以前要实现就需要以下的代码,是不是感觉比以前简便多了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <Button Width="300" Height="46" Content="关闭" Cursor="Hand" FontSize="20" Foreground="White"> <Button.Template> <ControlTemplate TargetType="{x:Type Button}"> <Border BorderBrush="{TemplateBinding Control.BorderBrush}" BorderThickness="0" CornerRadius="23"> <Border.Background>#4597FF</Border.Background> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Content="{TemplateBinding ContentControl.Content}" /> </Border> </ControlTemplate> </Button.Template> </Button>
|
事件
单击事件
1 2 3 4
| <Button Background="Transparent" Click="AnsItemClick" Tag="{Binding}" />
|
代码
1 2 3 4
| private void AnsItemClick(object sender, RoutedEventArgs e) { Console.WriteLine(@"单击事件"); }
|
双击事件
方式1
XAML:
1
| <Button Content="Click Me" MouseDoubleClick="Button_MouseDoubleClick"/>
|
C#:
1 2 3 4 5
| private void Button_MouseDoubleClick(object sender, MouseButtonEventArgs e) { MessageBox.Show("Double clicked!"); }
|
注意
这样双击事件触发的时候,同时也触发了两次单击事件。
方式2
WPF提供了一专门处理双击事件的事件类型,即PreviewMouseDoubleClick。
这个事件会在双击时触发,可以在这里处理双击事件逻辑,并避免触发单击事件。
XAML部分:
1
| <Button Content="双击我" PreviewMouseDoubleClick="Button_PreviewMouseDoubleClick" />
|
代码部分:
1 2 3 4 5 6 7 8
| private void Button_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e) { MessageBox.Show("双击事件发生了!"); e.Handled = true; }
|
当双击按钮时,会触发Button_PreviewMouseDoubleClick方法。
在方法中,处理双击事件的逻辑并设置e.Handled = true可以防止单击事件继续传播。
注意
这样只能避免第二次的点击事件不触发单击事件,双击中的第一次依旧会触发单击事件。
方式3
1 2 3 4
| <Button Background="Transparent" PreviewMouseDown="AnsItemDbClick" Tag="{Binding}" />
|
代码
1 2 3 4 5 6 7 8 9 10 11 12
| private void AnsItemDbClick(object sender, MouseButtonEventArgs e) { if (e.ClickCount > 1) { Console.WriteLine(@"双击事件"); e.Handled = true; } else { Console.WriteLine(@"单击事件"); } }
|
注意
这样只能避免第二次的点击事件不触发单击事件,双击中的第一次依旧会触发单击事件。
双击不触发点击事件
如果我们想触发双击事件的时候,不触发单击事件,我们只能延迟执行我们的单击事件。
1 2
| <Button Content="Click Me" PreviewMouseDown="Button_PreviewMouseDown"/>
|
当点击下的时候设置一个延迟执行的定时任务,如果任务还没触发的时候,双击了,取消之前的定时任务,不过这样单击任务都会延迟执行,体验不是很好。
目前没有别的方式。