在進行WPF界面設計時,我們需要在很多地方設置顏色屬性,比如元素的背景色、前景色以及邊框的顏色,還有形狀的內部填充和筆畫,這些顏色的設置在WPF中都以畫刷(Brush)的形式實現。比如最常用的畫刷就是SolidColorBrush,它表示一種純色。 public abstract class Bru ...
在進行WPF界面設計時,我們需要在很多地方設置顏色屬性,比如元素的背景色、前景色以及邊框的顏色,還有形狀的內部填充和筆畫,這些顏色的設置在WPF中都以畫刷(Brush)的形式實現。比如最常用的畫刷就是SolidColorBrush,它表示一種純色。
public abstract class Brush : Animatable, IFormattable, IResource { public static readonly DependencyProperty OpacityProperty; public static readonly DependencyProperty TransformProperty; public static readonly DependencyProperty RelativeTransformProperty; protected Brush(); public double Opacity { get; set; } public Transform Transform { get; set; } public Transform RelativeTransform { get; set; } public Brush Clone(); public Brush CloneCurrentValue(); public override string ToString(); public string ToString(IFormatProvider provider); }
Brush繼承於Animatable基類和Freezable基類,說明它支持更改通知。如果改變了畫刷,任何使用該畫刷的控制項的顏色都會自動重繪。
Opacity 屬性表示它支持部分透明。
Brush一共有7個子類,下表中列出了它們的信息。
畫刷名稱 | 功能說明 |
SolidColorBrush | 使用單一的連續顏色填充區域 |
LinearGradientBrush | 使用線性漸變繪製區域。 |
RadialGradientBrush | 使用徑向漸變繪製區域。 焦點定義漸變的開始,而圓定義漸變的終點。 |
ImageBrush | 使用圖像繪製區域。 |
VisualBrush | 使用一個視圖繪製區域。 |
BitmapCacheBrush | 繪製帶有緩存的內容的區域。 |
DrawingBrush | 使用包括形狀、文本、視頻、圖像或其他繪製項等填充區域。 |
Brush基類和子類的繼承關係
SolidColorBrush純色畫刷
SolidColorBrush繼承於Brush抽象類,表示用某一種顏色填充區域。從定義上看,它擁有一個Color屬性,表示具體的顏色值。
public sealed class SolidColorBrush : Brush { public static readonly DependencyProperty ColorProperty; public SolidColorBrush(); public SolidColorBrush(Color color); public Color Color { get; set; } public static object DeserializeFrom(BinaryReader reader); public SolidColorBrush Clone(); public SolidColorBrush CloneCurrentValue(); }
Color 在WPF中代表顏色值,被設計成一個結構體,主要是4個屬性,即A、R、G、B,分別表示Alpha透明通道值,紅色通道值、綠色通道值和藍色通道值。它們的取值範圍都是0-255
案列:
設置Grid的背景顏色
<Grid> <Grid.Background> <SolidColorBrush> <SolidColorBrush.Color> <Color A="255" R="255" G="0" B="0"/> </SolidColorBrush.Color> </SolidColorBrush> </Grid.Background> </Grid>
C#代碼的方式去設置背景顏色
SolidColorBrush solidColorBrush = new SolidColorBrush(); //使用系統自定義的顏色 solidColorBrush.Color = Colors.Green; //或者從Color的FromRgb成員中得到顏色 solidColorBrush.Color = Color.FromRgb(0, 0x80, 0); grid.Background = solidColorBrush;
實例化成一個資源:
<Window.Resources> <SolidColorBrush x:Key="BackgroundBrush" Color="#123456"/> </Window.Resources> <Grid x:Name="grid" Background="{StaticResource BackgroundBrush}"/>
LinearGradientBrush漸變畫刷
LinearGradientBrush是一個比較有意思的畫刷,它可以從一種顏色過渡到另一種顏色,使被填充的區域呈現漸變效果
public sealed class LinearGradientBrush : GradientBrush { public static readonly DependencyProperty StartPointProperty; public static readonly DependencyProperty EndPointProperty; public LinearGradientBrush(); public LinearGradientBrush(GradientStopCollection gradientStopCollection); public LinearGradientBrush(GradientStopCollection gradientStopCollection, double angle); public LinearGradientBrush(Color startColor, Color endColor, double angle); public LinearGradientBrush(GradientStopCollection gradientStopCollection, Point startPoint, Point endPoint); public LinearGradientBrush(Color startColor, Color endColor, Point startPoint, Point endPoint); public Point StartPoint { get; set; } public Point EndPoint { get; set; } public LinearGradientBrush Clone(); public LinearGradientBrush CloneCurrentValue(); }
從定義上看,它有StartPoint 和EndPoint 兩個點,表示獲取和設置線性漸變的二維起始坐標和結束坐標。而它因為繼承於GradientBrush基類,所以它的顏色都保存在GradientStops集合屬性中。GradientStops集合中的元素類型必須為GradientStop,表示漸變中轉換點的位置和顏色。所以,GradientStop擁有Color屬性和Offset屬性,分別表示顏色值和偏移值。
案例:
一個Grid,希望從左上角設置一個綠色,右下角設置一個藍色,中間是兩種顏色的漸變效果
<Grid> <Grid.Background> <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"> <GradientStop Color="Green" Offset="0"/> <GradientStop Color="Blue" Offset="1"/> </LinearGradientBrush> </Grid.Background> </Grid>
LinearGradientBrush將整個Grid看成是一個0-1的矩形,所以StartPoint=(0,0)表示左上角,EndPoint=(1,1)表示右下角,這就控制了漸變的方向是從左上角到右下角的斜線。GradientStop 對象中的Offset表示在漸變方向上各顏色的占比或起點。假如我們將第一個GradientStop對象的Offset設置為0.5,那麼此時的代碼和效果如下所示:
<Grid> <Grid.Background> <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"> <GradientStop Color="Green" Offset="0.5"/> <GradientStop Color="Blue" Offset="1"/> </LinearGradientBrush> </Grid.Background> </Grid>
RadialGradientBrush徑向漸變
RadialGradientBrush徑向漸變像一個圓一樣,從焦點中心位置開始向四周漸變,LinearGradientBrush線性漸變具有用於定義漸變矢量的起點和終點,而徑向漸變具有一個圓和一個焦點,用於定義漸變行為。 圓定義漸變的終點。 換句話說,漸變停止點為 1.0 定義圓周的顏色。 焦點定義漸變的中心。 漸變停止點為 0.0 定義焦點處的顏色。
public sealed class RadialGradientBrush : GradientBrush { public static readonly DependencyProperty CenterProperty; public static readonly DependencyProperty RadiusXProperty; public static readonly DependencyProperty RadiusYProperty; public static readonly DependencyProperty GradientOriginProperty; public RadialGradientBrush(); public RadialGradientBrush(GradientStopCollection gradientStopCollection); public RadialGradientBrush(Color startColor, Color endColor); public Point Center { get; set; } public double RadiusX { get; set; } public double RadiusY { get; set; } public Point GradientOrigin { get; set; } public RadialGradientBrush Clone(); public RadialGradientBrush CloneCurrentValue(); }
Center屬性:獲取或設置徑向漸變的最外面圓的中心。
RadiusX屬性:獲取或設置徑向漸變的最外面圓的水平半徑。預設值為 0.5。
RadiusY屬性:獲取或設置徑向漸變的最外面圓的垂直半徑。預設值為 0.5。
GradientOrigin屬性:獲取或設置用於定義漸變開始的二維焦點的位置。預設值為 0.5。
以Ellipse控制項為例,演示一下RadialGradientBrush 的用法:
<Grid x:Name="grid"> <Ellipse Width="200" Height="200"> <Ellipse.Fill> <RadialGradientBrush GradientOrigin="0.5,0.5" RadiusX="0.75" RadiusY="0.75"> <RadialGradientBrush.GradientStops> <GradientStop Color="White" Offset="0" /> <GradientStop Color="Black" Offset="0.65" /> <GradientStop Color="Gray" Offset="0.8" /> </RadialGradientBrush.GradientStops> </RadialGradientBrush> </Ellipse.Fill> </Ellipse> </Grid>
在上面的代碼中,處於圓中心的白色漸變點由GradientOrigin屬性控制,如果將值改成:GradientOrigin="0.25,0.25",那麼它會呈現下麵的樣子。
根據這個特性,我們可以實現一個有趣的示例。那就是當滑鼠移動到橢圓內,這個徑向漸變的起點坐標跟隨滑鼠位置變化而變化。
<Grid x:Name="grid"> <Ellipse x:Name="ellipse" Width="200" Height="200" MouseMove="ellipse_MouseMove"> <Ellipse.Fill> <RadialGradientBrush GradientOrigin="0.25,0.25" RadiusX="0.75" RadiusY="0.75"> <RadialGradientBrush.GradientStops> <GradientStop Color="White" Offset="0" /> <GradientStop Color="Goldenrod" Offset="0.65" /> <GradientStop Color="Gray" Offset="0.8" /> </RadialGradientBrush.GradientStops> </RadialGradientBrush> </Ellipse.Fill> </Ellipse> </Grid>
private void ellipse_MouseMove(object sender, MouseEventArgs e) { Ellipse ellipse = e.Source as Ellipse; Point point = e.GetPosition(ellipse); double width = ellipse.Width; double height = ellipse.Height; RadialGradientBrush brush = ellipse.Fill as RadialGradientBrush; double x = point.X / width; double y = point.Y / height; brush.GradientOrigin = new Point(x, y); }
ImageBrush圖像畫刷
ImageBrush表示使用圖像繪製區域。它繼承於TileBrush抽象基類,另外,DrawingBrush和VisualBrush也繼承於TileBrush抽象基類。
TileBrush 有三種不同類型,其中每一種都使用不同類型的內容進行繪製。下麵列出它3個子類的情況。
- 若使用ImageBrush子類,則畫刷的填充內容是圖像;
- 若使用DrawingBrush子類,則畫刷的填充內容是繪圖;
- 若使用VisualBrush子類,則畫刷的填充內容是視覺對象(視覺樹或控制項);
public abstract class TileBrush : Brush { public static readonly DependencyProperty ViewportUnitsProperty; public static readonly DependencyProperty ViewboxUnitsProperty; public static readonly DependencyProperty ViewportProperty; public static readonly DependencyProperty ViewboxProperty; public static readonly DependencyProperty StretchProperty; public static readonly DependencyProperty TileModeProperty; public static readonly DependencyProperty AlignmentXProperty; public static readonly DependencyProperty AlignmentYProperty; protected TileBrush(); public TileMode TileMode { get; set; } public Stretch Stretch { get; set; } public Rect Viewbox { get; set; } public Rect Viewport { get; set; } public AlignmentY AlignmentY { get; set; } public BrushMappingMode ViewportUnits { get; set; } public AlignmentX AlignmentX { get; set; } public BrushMappingMode ViewboxUnits { get; set; } public TileBrush Clone(); public TileBrush CloneCurrentValue(); protected abstract void GetContentBounds(out Rect contentBounds); }
TileMode 屬性:獲取或設置基本圖塊如何填充區域。枚舉型,它一共有5個值,Tile表示在可用區域複製圖像;FlipX表示覆製圖像但垂直翻轉每個第二列;FlipY表示覆製圖像但水平翻轉每個第二行;FlipXY表示覆製圖像,但是垂直翻轉每個第二列,半水平翻轉每個第二行。
Stretch 屬性:獲取或設置內容如何拉伸。
Viewbox 屬性:獲取或設置圖塊中內容的位置和尺寸。
Viewport 屬性:獲取或設置基本圖塊的位置和尺寸。它的類型是Rect,也就是用它來指定截取原圖片的某個區域進行填充,這個區域的設置可以用絕對值和相對值兩種方式設置,對應屬性是ViewboxUnits,它有兩個值,Absolute表示取絕對坐標,RelativeToBoundingBox表示取相對坐標。
AlignmentY屬性:獲取或設置基本圖塊的垂直對齊方式。
AlignmentX屬性:獲取或設置基本圖塊的垂直水平方式。
ViewboxUnits屬性:獲取或設置Viewbox的值是相對內容的邊界框而言,還是絕對值。
ViewportUnits屬性:獲取或設置Viewport的值 是否是相對於輸出區域的大小。
ImageBrush的定義:
public sealed class ImageBrush : TileBrush { public static readonly DependencyProperty ImageSourceProperty; public ImageBrush(); public ImageBrush(ImageSource image); public ImageSource ImageSource { get; set; } public ImageBrush Clone(); public ImageBrush CloneCurrentValue(); protected override Freezable CreateInstanceCore(); protected override void GetContentBounds(out Rect contentBounds); }
ImageBrush 畫刷只需要設置它的ImageSource 屬性,其它的屬性都是從它的基類TileBrush繼承而來
案例:
<Grid x:Name="grid"> <Grid.Background> <ImageBrush ImageSource="/Images/lyf.png" Stretch="UniformToFill" TileMode="Tile"> <ImageBrush.Viewport> <Rect X="0" Y="0" Width="1" Height="1"/> </ImageBrush.Viewport> </ImageBrush> </Grid.Background> </Grid>
在上面的代碼中,我們給Grid控制項設置了一個ImageBrush 圖像畫刷,並設置Stretch為UniformToFill,即自適應填充,同時設置了Viewport。那麼它運行之後呈現的效果如下:
此時的Grid的背景其實就是一張圖片。我們給Window對象的MouseWheel事件訂閱了一個回調函數,併在其實改變了Viewport的寬度和高度。滾動滑鼠的滾輪,此時Grid的背景圖像的填充將會呈現如下的樣子:
private void Window_MouseWheel(object sender, MouseWheelEventArgs e) { double offset = e.Delta / 3600.0; ImageBrush imageBrush = grid.Background as ImageBrush; Rect rect = imageBrush.Viewport; if (rect.Width + offset <= 0 && rect.Height + offset <= 0) return; rect.Width += offset; rect.Height += offset; imageBrush.Viewport = rect; }