前言
無論是在PC客戶端,移動端,網(wǎng)站偎蘸,在遇到長時間處理的時候都會需要用到蒙罩層,讓用戶有更好的體現(xiàn)瞬内。今天上網(wǎng)逛了一下各位前輩網(wǎng)友的蒙罩層的實現(xiàn)方式迷雪,覺得有很多都搞復(fù)雜了(利用前臺代碼+后臺代碼+數(shù)學(xué)計算),無疑增加了維護的難度遂鹊。然而振乏,本人參考了各位前輩的實現(xiàn)以后,自己實現(xiàn)了一個可重用LoadingPage控件秉扑,歡迎各位下載使用慧邮。
需求
需求先行是必須的,我的目標(biāo)是做成怎樣一個效果呢舟陆?
1. 是一個控件误澳,可以在.NET各環(huán)境中得以重用。
2. 可配置秦躯,例如顏色忆谓,大小,提醒字符串等等的屬性踱承,用戶可以自定義倡缠,以滿足用戶所在情況的需求哨免。
3. 大小比例自適應(yīng),不同大小的窗口載體昙沦,能自動改變自身大小比例琢唾。
4. 效果全部xaml實現(xiàn),全部集中于xaml可控制難度不會大盾饮,維護起來方便采桃,用戶拷貝xaml也方便。
解決方法
1. 新建WPF用戶控件庫進行開發(fā)丘损。
2. 使用依賴項屬性普办,然后前臺xaml使用屬性綁定來實現(xiàn)。
3. 使用ViewBox控件(該控件能夠自動縮放內(nèi)容)徘钥。
4. 在xaml中的寫動畫代碼衔蹲。
結(jié)果展示
制作過程
1. 新建一個"WPF用戶控件庫"工程,新建一個WPF控件吏饿。(這步不解釋)
2. 為了實現(xiàn)蒙罩效果踪危,我們把控件的背景弄成黑色背景,并且透明度為0.2猪落。
<UserControl.Background>
<SolidColorBrush Color="Black" Opacity="0.2" ></SolidColorBrush>
</UserControl.Background>
3. 然后就是先利用Canvas作為背景贞远,在其上畫一個由小圓圈構(gòu)成的大圈,使用控件Ellipse笨忌。
<Canvas RenderTransformOrigin="0.5,0.5"
HorizontalAlignment="Center" x:Name="loadCancas"
VerticalAlignment="Center" Width="120"
Height="120" >
<Canvas.Resources>
<Style TargetType="Ellipse">
<Setter Property="Width" Value="10" ></Setter>
<Setter Property="Height" Value="10" ></Setter>
<Setter Property="Canvas.Left" Value="30"></Setter>
<Setter Property="Canvas.Top" Value="30"></Setter>
<Setter Property="Stretch" Value="Fill"></Setter>
<Setter Property="Fill" Value="Blue"></Setter>
<Setter Property="RenderTransformOrigin" Value="3,3"></Setter>
</Style>
</Canvas.Resources>
<Ellipse >
</Ellipse>
<Ellipse Opacity="0.9">
<Ellipse.RenderTransform>
<TransformGroup>
<RotateTransform Angle="36"/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
<Ellipse Opacity="0.8">
<Ellipse.RenderTransform>
<TransformGroup>
<RotateTransform Angle="72"/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
<Ellipse Opacity="0.7">
<Ellipse.RenderTransform>
<TransformGroup>
<RotateTransform Angle="108"/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
<Ellipse Opacity="0.6">
<Ellipse.RenderTransform>
<TransformGroup>
<RotateTransform Angle="144"/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
<Ellipse Opacity="0.5">
<Ellipse.RenderTransform>
<TransformGroup>
<RotateTransform Angle="180"/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
<Ellipse Opacity="0.4">
<Ellipse.RenderTransform>
<TransformGroup>
<RotateTransform Angle="216"/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
<Ellipse Opacity="0.3">
<Ellipse.RenderTransform>
<TransformGroup>
<RotateTransform Angle="252"/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
<Ellipse Opacity="0.2">
<Ellipse.RenderTransform>
<TransformGroup>
<RotateTransform Angle="288"/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
<Ellipse Opacity="0.1" >
<Ellipse.RenderTransform>
<TransformGroup>
<RotateTransform Angle="324"/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
<Canvas.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="SpinnerRotate"
Angle="0" />
</TransformGroup>
</Canvas.RenderTransform>
</Canvas>
</Grid>
這樣就形成了一個圈蓝仲,然后為了實現(xiàn)目標(biāo)3(內(nèi)容能自動改變大小),使用一個viewBox作為容器官疲,包住這個Canvas袱结。(不貼代碼了)
4. 旋轉(zhuǎn)動畫編寫。
因為我在Canvas畫了一個圈途凫,然而我只需無限旋轉(zhuǎn)Canvas便可實現(xiàn)像小圓圈在動一樣垢夹。下面看一下Canvas的觸發(fā)器,在觸發(fā)器中實現(xiàn)動畫的編寫维费。
<Canvas.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard Name="loadAnimation">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="loadCancas" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(RotateTransform.Angle)" From="360" To="0" RepeatBehavior="Forever" Duration="0:0:3"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Unloaded">
<StopStoryboard BeginStoryboardName="loadAnimation"></StopStoryboard>
</EventTrigger>
</Canvas.Triggers>
5. 屬性可配置果元,使用依賴屬性,并且在xaml中寫綁定犀盟,下面先看后臺代碼中的依賴項屬性的定義阅畴,然后前臺綁定就補貼了,統(tǒng)一在附件中可以看到。
public partial class LoadingPage : UserControl
{
public LoadingPage()
{
InitializeComponent();
}
#region 加載圓圈的margin
[DescriptionAttribute("加載圓圈的margin"), CategoryAttribute("擴展"), DefaultValueAttribute(0)]
public string LoadCirclesMargin
{
get { return (string)GetValue(LoadCirclesMarginProperty); }
set { SetValue(LoadCirclesMarginProperty, value); }
}
public static readonly DependencyProperty LoadCirclesMarginProperty =
DependencyProperty.Register("LoadCirclesMargin", typeof(string), typeof(LoadingPage),
new FrameworkPropertyMetadata("50"));
#endregion
#region 加載中的提示
[DescriptionAttribute("加載中的提示"), CategoryAttribute("擴展"), DefaultValueAttribute(0)]
public string LoadingText
{
get { return (string)GetValue(LoadingTextProperty); }
set { SetValue(LoadingTextProperty, value); }
}
public static readonly DependencyProperty LoadingTextProperty =
DependencyProperty.Register("LoadingText", typeof(string), typeof(LoadingPage),
new FrameworkPropertyMetadata("加載中"));
#endregion
#region 加載中的提示的字體大小
[DescriptionAttribute("加載中的提示的字體大小"), CategoryAttribute("擴展"), DefaultValueAttribute(0)]
public int LoadingTextFontSize
{
get { return (int)GetValue(LoadingTextFontSizeProperty); }
set { SetValue(LoadingTextFontSizeProperty, value); }
}
public static readonly DependencyProperty LoadingTextFontSizeProperty =
DependencyProperty.Register("LoadingTextFontSize", typeof(int), typeof(LoadingPage),
new FrameworkPropertyMetadata(12));
#endregion
#region 圓圈的顏色
[DescriptionAttribute("圓圈的顏色"), CategoryAttribute("擴展"), DefaultValueAttribute(0)]
public Brush CirclesBrush
{
get { return (Brush)GetValue(CirclesBrushProperty); }
set { SetValue(CirclesBrushProperty, value); }
}
public static readonly DependencyProperty CirclesBrushProperty =
DependencyProperty.Register("CirclesBrush", typeof(Brush), typeof(LoadingPage),
new FrameworkPropertyMetadata(Brushes.Black));
#endregion
#region 加載中的提示的字體顏色
[DescriptionAttribute("加載中的提示的字體顏色"), CategoryAttribute("擴展"), DefaultValueAttribute(0)]
public Brush LoadingTextForeground
{
get { return (Brush)GetValue(LoadingTextForegroundProperty); }
set { SetValue(LoadingTextForegroundProperty, value); }
}
public static readonly DependencyProperty LoadingTextForegroundProperty =
DependencyProperty.Register("LoadingTextForeground", typeof(Brush), typeof(LoadingPage),
new FrameworkPropertyMetadata(Brushes.DarkSlateGray));
#endregion
}
大功告成;菏臁Kん浴!彰触!上面的代碼都是為了展示原理而分拆出來的零碎代碼况毅,如果想使用該控件尔许,可以點下面的