天天看點

WPF自定義控件08:FlatRoundImage

       在不少的應用程式中,使用者中心的個人頁面經常需要顯示頭像,這個目前主流的做法就是使用者上傳一個圖檔,系統進行截取并顯示為一個圓形的輪廓,即圓形的照片。本文将介紹一下自定義的圖檔控件FlatRoundImage,它是一個UserControl控件,自身攜帶UI樣式和背景邏輯。下面将詳細介紹具體的實作細節。

1 WPF項目結構

    基于之前建立的WPF示例項目,在其中建立一個新的關于FlatRoundImage的使用者控件項目檔案。添加過程如下圖所示:

WPF自定義控件08:FlatRoundImage

添加成功後,本項目檔案結構,如下圖所示:

WPF自定義控件08:FlatRoundImage

與之前的自定義控件不同,使用者控件類型的項目檔案UI和背景邏輯是在一起的,這樣也非常的友善。另外,這種方式建立的自定義控件不需要将其注冊到Generic.xaml檔案中。

2 WPF FlatRoundImage實作

    首先,在控件的UI界面上,UserControl類的控件原生帶有UI布局,即像一個視窗一樣,可以通過拖入已有的控件進行UI設計,是以從布局到功能上都更加的友善。FlatRoundImage控件,布局界面如下:

WPF自定義控件08:FlatRoundImage

其中的核心代碼如下:

<UserControl x:Class="Yd.WpfControls.FlatRoundImage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Yd.WpfControls"
             mc:Ignorable="d" 
             Width="100"
             Height="100"
             BorderThickness="0"
             RenderOptions.BitmapScalingMode="HighQuality"
             UseLayoutRounding="True"
             TextOptions.TextFormattingMode="Display"
             d:DesignHeight="100" d:DesignWidth="100" x:Name="uc">
    <Grid>
        <Ellipse Width="{Binding ElementName=uc, Path=Width}" 
                 Height="{Binding ElementName=uc, Path=Width}" 
                 StrokeThickness="1" 
                 SnapsToDevicePixels="True"
                 Stroke="{Binding ElementName=uc, Path=Stroke}" >
            <Ellipse.Fill>
                <ImageBrush x:Name="PART_IMG" 
                            ImageSource="{Binding ElementName=uc, Path=ImgSource}"  />
    <!--<ImageBrush x:Name="PART_IMG" ImageSource="{Binding ImgSource}" /> not work-->
            </Ellipse.Fill>
        </Ellipse>
    </Grid>
</UserControl>
      

其中的圓形邊框是通過Ellipse實作的,設定長度和寬度一緻,即是圓形。 StrokeThickness="1" 表示邊框寬度為1。圓形中的背景圖是通過Ellipse.Fill屬性的,給出了ImageBrush對象,它具有ImageSource屬性,可綁定具體的圖檔URI。這裡需要注意一下:ImageSource="{Binding ElementName=uc, Path=ImgSource}"這種綁定是成功的,而ImageSource="{Binding ImgSource}"是無法正确綁定屬性的。

下面再給出FlatRoundImage自定義控件的背景代碼,具體如下所示:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Yd.WpfControls
{
    /// <summary>
    /// FlatRoundImage.xaml 的互動邏輯
    /// </summary>
    public partial class FlatRoundImage : UserControl
    {
        public FlatRoundImage()
        {
            InitializeComponent();
        }
       
        public static readonly DependencyProperty ImgSourceProperty =
        DependencyProperty.Register("ImgSource", typeof(string), typeof(FlatRoundImage)
            ,new PropertyMetadata("/Image/avatar.png"));
        public string ImgSource
        {
            get { return (string)GetValue(ImgSourceProperty); }
            set
            {
                SetValue(ImgSourceProperty, value);
            }
        }

        public static readonly DependencyProperty StrokeProperty =
   DependencyProperty.Register("Stroke", typeof(Brush), typeof(FlatRoundImage)
       , new PropertyMetadata(Brushes.Silver));
        public Brush Stroke
        {
            get { return (Brush)GetValue(StrokeProperty); }
            set
            {
                SetValue(StrokeProperty, value);
            }
        }

    }
}      

其中定義了兩個控件的依賴屬性,即ImgSource和Stroke,一個代表背景圖檔的位址,一個代表邊框的顔色。

3 WPF FlatRoundImage測試

    首先,需要重新生成一下項目檔案,然後在WpfControls項目中添加一個視窗Window6,并在此視窗中添加自定義控件FlatRoundImage,Window6.xaml部分示例代碼如下:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfControls"
        xmlns:WpfControls="clr-namespace:Yd.WpfControls;assembly=Yd.WpfControls" x:Class="WpfControls.Window6"
        mc:Ignorable="d"
        Title="Window6" Height="350" Width="400">
    <Grid Background="Green">

        <WpfControls:FlatRoundImage HorizontalAlignment="Center" Margin="0,93,0,0" 
                  VerticalAlignment="Top" ImgSource="/Image/avatar.png"/>

        <WpfControls:FlatRoundImage HorizontalAlignment="Center" Margin="0,222,0,0" 
                  Height="60" Width="60"
                  VerticalAlignment="Top" ImgSource="/Image/avatar.png"/>

    </Grid>
</Window>
      

另外需要注意的就是,圖檔路徑如果無法找到,則可能需要進行圖檔素材的輸出資源配置,将其作為資源輸出到目錄中,示意圖如下所示:

WPF自定義控件08:FlatRoundImage

運作界面如下:

WPF自定義控件08:FlatRoundImage