若在WPF中,實現Button按鈕添加圖片,有如下2種方式
方式一:修改控件模板
方式二:Button中添加Image圖片控件
方式三:自定義按鈕控件
方式一:修改控件模板
在WPF中,如果要想給按鈕控件Button加上圖片,最直接的做法是修改控件模板,在模板中加入想要的圖片,代碼如下圖所示:
<Button x:Name="btn" Width="50" Margin="40,40,103,321.667" Click="btn_Click"> <Button.Template> <ControlTemplate> <Grid> <Image Margin="2" Source="img/1.jpg" /> </Grid> </ControlTemplate> </Button.Template> </Button>
效果如下圖 (備注:窗體的背景色為黑色)
但是這樣做有一個弊端——每次需要用到圖片按鈕的時候都要去修改模板。
因為上面的示例代碼中,模板代碼過於精簡,所以乍看之下似乎這種做法也沒有什么不好。
但是在實際的應用中,按鈕控件的模板往往復雜得多,比如,有很多的Trigger事件,往往需要根據鼠標或按鈕的狀態來調整控件的圖片、字體、背景等狀態。
因此,如果每次應用圖片控件的時候都修改模板,很可能會導致xaml文件的代碼量爆炸。
方式二:Button中添加Image控件
<Button x:Name="btnSet" Width="50" Height="50" Click="btnSet_Click"> <Image Source="img/1.jpg" Width="45" Height="45"></Image> </Button>
效果如下圖 (備注:窗體的背景色為黑色)
這種方式,沒有辦法把文字顯示在按鈕中,若設置Button中Content的值,報錯信息如下,故圖片+文字用此方式不可取
方式三:自定義按鈕控件
一個可行的解決方案為,封裝一個用於圖片按鈕的自定義按鈕控件,該控件繼承自Button控件,但是額外增加了一些用戶圖片綁定的依賴屬性,同時在控件的默認外觀模板中,通過TemplateBinding的方式綁定到依賴屬性上,這樣在使用的時候便可以直接通過綁定的方式設置圖片按鈕需要顯示的圖片,不再需要修改控件模板。
其實現步驟如下
一、代碼結構
如圖所示,采用自定義控件(CustomControl)的方式對Button控件進行封裝。
其中ImageButton.xaml為默認控件模板,ImageButton.cs為控件的邏輯控制文件,
其中包含了ImageButton控件所需要的新的依賴屬性,包括圖片源屬性等。
二、模板代碼
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:CustomControl"> <Style TargetType="{x:Type local:ImageButton}"> <Setter Property="Cursor" Value="Hand"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:ImageButton}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <Grid x:Name="grid" Background="{TemplateBinding Background}"> <Border x:Name="PART_Border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}"/> <Grid HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"> <StackPanel HorizontalAlignment="Center" Orientation="{TemplateBinding IconContentOrientation}" VerticalAlignment="Center" Margin="{TemplateBinding Padding}"> <Grid HorizontalAlignment="Center" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"> <Image x:Name="PART_Icon" Source="{TemplateBinding Icon}" Height="{TemplateBinding IconHeight}" Width="{TemplateBinding IconWidth}"/> <Image x:Name="PART_MouseOverIcon" Visibility="Collapsed" Source="{TemplateBinding IconMouseOver}" Height="{TemplateBinding IconHeight}" Width="{TemplateBinding IconWidth}"/> <Image x:Name="PART_PressIcon" Visibility="Collapsed" Source="{TemplateBinding IconPress}" Height="{TemplateBinding IconHeight}" Width="{TemplateBinding IconWidth}"/> </Grid> <TextBlock x:Name="PART_Content" Text="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Margin="{TemplateBinding IconContentMargin}" Foreground="{TemplateBinding Foreground}" TextTrimming="CharacterEllipsis"/> </StackPanel> </Grid> </Grid> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Foreground" TargetName="PART_Content" Value="{Binding MouseOverForeground,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ImageButton}}}"/> <Setter Property="Background" TargetName="PART_Border" Value="{Binding MouseOverBackground,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ImageButton}}}"/> <Setter Property="BorderBrush" TargetName="PART_Border" Value="{Binding MouseOverBorderBrush,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ImageButton}}}"/> <Setter Property="Visibility" TargetName="PART_MouseOverIcon" Value="Visible"/> <Setter Property="Visibility" TargetName="PART_Icon" Value="Collapsed"/> <Setter Property="Visibility" TargetName="PART_PressIcon" Value="Collapsed"/> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="Foreground" TargetName="PART_Content" Value="{Binding MouseDownForeground,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ImageButton}}}"/> <Setter Property="Background" TargetName="PART_Border" Value="{Binding MouseDownBackground,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ImageButton}}}"/> <Setter Property="BorderBrush" TargetName="PART_Border" Value="{Binding MouseDownBorderBrush,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ImageButton}}}"/> <Setter Property="Visibility" TargetName="PART_PressIcon" Value="Visible"/> <Setter Property="Visibility" TargetName="PART_Icon" Value="Collapsed"/> <Setter Property="Visibility" TargetName="PART_MouseOverIcon" Value="Collapsed"/> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="Opacity" Value="0.5" /> </Trigger> <Trigger Property="Text" SourceName="PART_Content" Value=""> <Setter Property="Visibility" TargetName="PART_Content" Value="Collapsed"/> </Trigger> <Trigger Property="Text" SourceName="PART_Content" Value="{x:Null}"> <Setter Property="Visibility" TargetName="PART_Content" Value="Collapsed"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
在模板中,通過TemplateBinding 的方式綁定了控件中的自定義屬性,並默認顯示給定的圖標和文字。
然后通過觸發器,當鼠標懸停或按下的時候,控制相關圖標的顯示隱藏以及文字的背景色、前景色和邊框顏色。
三、自定義依賴屬性
在ImageButton.cs中定義依賴屬性,這些依賴屬性包含了圖片按鈕控件的邊框、前景色、背景色,圖片等屬性。在復寫的OnApplyTemplate方法中,會判斷如果某些依賴屬性的值為null,則使用默認屬性。
public class ImageButton : Button { static ImageButton() { DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton))); } public override void OnApplyTemplate() { base.OnApplyTemplate(); if (this.MouseOverBackground == null) { this.MouseOverBackground = Background; } if (this.MouseDownBackground == null) { if (this.MouseOverBackground == null) { this.MouseDownBackground = Background; } else { this.MouseDownBackground = MouseOverBackground; } } if (this.MouseOverBorderBrush == null) { this.MouseOverBorderBrush = BorderBrush; } if (this.MouseDownBorderBrush == null) { if (this.MouseOverBorderBrush == null) { this.MouseDownBorderBrush = BorderBrush; } else { this.MouseDownBorderBrush = MouseOverBorderBrush; } } if (this.MouseOverForeground == null) { this.MouseOverForeground = Foreground; } if (this.MouseDownForeground == null) { if (this.MouseOverForeground == null) { this.MouseDownForeground = Foreground; } else { this.MouseDownForeground = this.MouseOverForeground; } } } #region Dependency Properties /// <summary> /// 鼠標移上去的背景顏色 /// </summary> public static readonly DependencyProperty MouseOverBackgroundProperty = DependencyProperty.Register("MouseOverBackground", typeof(Brush), typeof(ImageButton)); /// <summary> /// 鼠標按下去的背景顏色 /// </summary> public static readonly DependencyProperty MouseDownBackgroundProperty = DependencyProperty.Register("MouseDownBackground", typeof(Brush), typeof(ImageButton)); /// <summary> /// 鼠標移上去的字體顏色 /// </summary> public static readonly DependencyProperty MouseOverForegroundProperty = DependencyProperty.Register("MouseOverForeground", typeof(Brush), typeof(ImageButton), new PropertyMetadata(null, null)); /// <summary> /// 鼠標按下去的字體顏色 /// </summary> public static readonly DependencyProperty MouseDownForegroundProperty = DependencyProperty.Register("MouseDownForeground", typeof(Brush), typeof(ImageButton), new PropertyMetadata(null, null)); /// <summary> /// 鼠標移上去的邊框顏色 /// </summary> public static readonly DependencyProperty MouseOverBorderBrushProperty = DependencyProperty.Register("MouseOverBorderBrush", typeof(Brush), typeof(ImageButton), new PropertyMetadata(null, null)); /// <summary> /// 鼠標按下去的邊框顏色 /// </summary> public static readonly DependencyProperty MouseDownBorderBrushProperty = DependencyProperty.Register("MouseDownBorderBrush", typeof(Brush), typeof(ImageButton), new PropertyMetadata(null, null)); /// <summary> /// 圓角 /// </summary> public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(ImageButton), null); //圖標 public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(ImageSource), typeof(ImageButton), null); //鼠標移上去的圖標圖標 public static readonly DependencyProperty IconMouseOverProperty = DependencyProperty.Register("IconMouseOver", typeof(ImageSource), typeof(ImageButton), null); //鼠標按下去的圖標圖標 public static readonly DependencyProperty IconPressProperty = DependencyProperty.Register("IconPress", typeof(ImageSource), typeof(ImageButton), null); //圖標高度 public static readonly DependencyProperty IconHeightProperty = DependencyProperty.Register("IconHeight", typeof(double), typeof(ImageButton), new PropertyMetadata(24.0, null)); //圖標寬度 public static readonly DependencyProperty IconWidthProperty = DependencyProperty.Register("IconWidth", typeof(double), typeof(ImageButton), new PropertyMetadata(24.0, null)); //圖標和內容的對齊方式 public static readonly DependencyProperty IconContentOrientationProperty = DependencyProperty.Register("IconContentOrientation", typeof(Orientation), typeof(ImageButton), new PropertyMetadata(Orientation.Horizontal, null)); //圖標和內容的距離 public static readonly DependencyProperty IconContentMarginProperty = DependencyProperty.Register("IconContentMargin", typeof(Thickness), typeof(ImageButton), new PropertyMetadata(new Thickness(0, 0, 0, 0), null)); #endregion #region Property Wrappers public Brush MouseOverBackground { get { return (Brush)GetValue(MouseOverBackgroundProperty); } set { SetValue(MouseOverBackgroundProperty, value); } } public Brush MouseDownBackground { get { return (Brush)GetValue(MouseDownBackgroundProperty); } set { SetValue(MouseDownBackgroundProperty, value); } } public Brush MouseOverForeground { get { return (Brush)GetValue(MouseOverForegroundProperty); } set { SetValue(MouseOverForegroundProperty, value); } } public Brush MouseDownForeground { get { return (Brush)GetValue(MouseDownForegroundProperty); } set { SetValue(MouseDownForegroundProperty, value); } } public Brush MouseOverBorderBrush { get { return (Brush)GetValue(MouseOverBorderBrushProperty); } set { SetValue(MouseOverBorderBrushProperty, value); } } public Brush MouseDownBorderBrush { get { return (Brush)GetValue(MouseDownBorderBrushProperty); } set { SetValue(MouseDownBorderBrushProperty, value); } } public CornerRadius CornerRadius { get { return (CornerRadius)GetValue(CornerRadiusProperty); } set { SetValue(CornerRadiusProperty, value); } } public ImageSource Icon { get { return (ImageSource)GetValue(IconProperty); } set { SetValue(IconProperty, value); } } public ImageSource IconMouseOver { get { return (ImageSource)GetValue(IconMouseOverProperty); } set { SetValue(IconMouseOverProperty, value); } } public ImageSource IconPress { get { return (ImageSource)GetValue(IconPressProperty); } set { SetValue(IconPressProperty, value); } } public double IconHeight { get { return (double)GetValue(IconHeightProperty); } set { SetValue(IconHeightProperty, value); } } public double IconWidth { get { return (double)GetValue(IconWidthProperty); } set { SetValue(IconWidthProperty, value); } } public Orientation IconContentOrientation { get { return (Orientation)GetValue(IconContentOrientationProperty); } set { SetValue(IconContentOrientationProperty, value); } } public Thickness IconContentMargin { get { return (Thickness)GetValue(IconContentMarginProperty); } set { SetValue(IconContentMarginProperty, value); } } #endregion }
四、控件的應用
應用控件的時候,只需要簡單的綁定控件的相關屬性即可。后續只需修改相關屬性便可實現相關效果
<local:ImageButton x:Name="btn_Image" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="Black" Margin="43,185,401.333,185.667" ToolTip="播放" Content="播放" Icon="img\file.png" IconMouseOver="img\data.png" IconPress="img\1.jpg" IconHeight="40" IconWidth="40" FontSize="16" IconContentMargin="10,0,0,0" Foreground="Gray" MouseOverForeground="#FFFFFF" MouseDownForeground="Blue" Grid.Column="1"/>
效果圖
1、正常狀態:
2、鼠標懸停狀態:
3、 鼠標按下狀態:
本文引自:https://blog.csdn.net/zhuo_wp/article/details/78350760