通过UserControl实例说明依赖属性和绑定
看一个简单例子
https://www.cnblogs.com/dotnet261010/p/6286475.html
先绘制原始circularprogressbar
<UserControl x:Class="WpfUITest1.Controls.CircularProgressBar" 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:WpfUITest1.Controls" mc:Ignorable="d" d:DesignHeight="150" d:DesignWidth="150"> <Grid Height="{Binding RelativeSource={RelativeSource Self},Path=Width}" Name="layout"> <Ellipse Width="{Binding ElementName=layout,Path=Width}" Height="{Binding ElementName=layout,Path=Width}" StrokeThickness="6" Stroke="#EEE" > <Ellipse.Effect> <DropShadowEffect ShadowDepth="0" Direction="0" Color="White" BlurRadius="5"/> </Ellipse.Effect> </Ellipse> <Path Name="path" Data="M75 3A75 75 0 0 1 147 75" StrokeThickness="4" Stroke="Orange" StrokeStartLineCap="Round" StrokeEndLineCap="Round"/> <!--M75 3A75 75 0 0 1 147 75--> <Viewbox Margin="20" > <TextBlock Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center"> <Run Text="25"></Run> <Run Text="%"></Run> </TextBlock> <!--{Binding Value,RelativeSource={RelativeSource AncestorType=UserControl,Mode=FindAncestor}}--> </Viewbox> </Grid> </UserControl>
例子1:使用依赖属性,添加进度值
后台
public partial class CircularProgressBar : UserControl { public double Value { get { return (double)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } public static DependencyProperty ValueProperty { get; } = DependencyProperty.Register("Value", typeof(double), typeof(CircularProgressBar), new PropertyMetadata(default(double), new PropertyChangedCallback(OnPropertyChanged))); public Brush BackColor { get { return (Brush)GetValue(BackColorProperty); } set { SetValue(BackColorProperty, value); } } public static readonly DependencyProperty BackColorProperty = DependencyProperty.Register("BackColor", typeof(Brush), typeof(CircularProgressBar), new PropertyMetadata(Brushes.LightGray)); public Brush ForeColor { get { return (Brush)GetValue(ForeColorProperty); } set { SetValue(ForeColorProperty, value); } } public static readonly DependencyProperty ForeColorProperty = DependencyProperty.Register("ForeColor", typeof(Brush), typeof(CircularProgressBar), new PropertyMetadata(Brushes.Orange)); public CircularProgressBar() { InitializeComponent(); this.SizeChanged += CircularProgressBar_SizeChanged; } private void CircularProgressBar_SizeChanged(object sender, SizeChangedEventArgs e) { UpdateValue(); } private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { (d as CircularProgressBar).UpdateValue(); } private void UpdateValue() { this.layout.Width=Math.Min(RenderSize.Width, RenderSize.Height); double radius = Math.Min(RenderSize.Width, RenderSize.Height) / 2; if (radius <= 0) return; double newValue = this.Value % 100.0; double newX = 0.0, newY = 0.0; newX = radius + (radius - 3) * Math.Cos((newValue * 3.6 - 90) * Math.PI / 180); newY = radius + (radius - 3) * Math.Sin((newValue * 3.6 - 90) * Math.PI / 180); //M75 3A75 75 0 0 1 147 75 string pathDataStr = "M{0} 3A{1} {1} 0 {4} 1 {2} {3}"; pathDataStr = string.Format(pathDataStr, radius + 0.01, radius - 3, newX, newY, newValue < 50 && newValue > 0 ? 0 : 1 ); var converter = TypeDescriptor.GetConverter(typeof(Geometry)); this.path.Data = (Geometry)converter.ConvertFrom(pathDataStr); } }
前端 绑定
<UserControl x:Class="WpfUITest1.Controls.CircularProgressBar" 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:WpfUITest1.Controls" mc:Ignorable="d" d:DesignHeight="150" d:DesignWidth="150"> <Grid Height="{Binding RelativeSource={RelativeSource Self},Path=Width}" Name="layout"> <Ellipse Width="{Binding ElementName=layout,Path=Width}" Height="{Binding ElementName=layout,Path=Width}" StrokeThickness="6" Stroke="{Binding BackColor,RelativeSource={RelativeSource AncestorType=UserControl,Mode=FindAncestor}}" > <Ellipse.Effect> <DropShadowEffect ShadowDepth="0" Direction="0" Color="White" BlurRadius="5"/> </Ellipse.Effect> </Ellipse> <Path Name="path" StrokeThickness="4" Stroke="{Binding ForeColor,RelativeSource={RelativeSource AncestorType=UserControl,Mode=FindAncestor}}" StrokeStartLineCap="Round" StrokeEndLineCap="Round"/> <!--M75 3A75 75 0 0 1 147 75--> <Viewbox Margin="20" > <TextBlock Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center"> <Run Text="{Binding Value,RelativeSource={RelativeSource AncestorType=UserControl,Mode=FindAncestor}}"></Run> <Run Text="%"></Run> </TextBlock> <!--{Binding Value,RelativeSource={RelativeSource AncestorType=UserControl,Mode=FindAncestor}}--> </Viewbox> </Grid> </UserControl>
如何使用
<UserControl 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:WpfUITest1.View" xmlns:Controls="clr-namespace:WpfUITest1.Controls" x:Class="WpfUITest1.View.SystemMonitor" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> <Canvas/> <Grid VerticalAlignment="Top"> <Grid.ColumnDefinitions> <ColumnDefinition Width="320"/> <ColumnDefinition/> <ColumnDefinition Width="300"/> </Grid.ColumnDefinitions> <Grid Grid.Column="2"> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> </Grid.RowDefinitions> <TextBlock Text="系统总览" Foreground="White" FontSize="16" HorizontalAlignment="Right" Margin="0,0,20,0"/> <UniformGrid Rows="1" Grid.Row="1" Margin="0,40,0,0"> <StackPanel> <TextBlock Text="监控值" HorizontalAlignment="Center" Foreground="#99FFFFFF"/> <Controls:CircularProgressBar Value="70" Width="60" Height="90" ForeColor="#20c9b4"/> <!--ForeColor="#20c9b4"--> </StackPanel> <StackPanel> <TextBlock Text="监控值" HorizontalAlignment="Center" Foreground="#99FFFFFF"/> <Controls:CircularProgressBar Value="50" Width="60" Height="90"/> </StackPanel> <StackPanel> <TextBlock Text="监控值" HorizontalAlignment="Center" Foreground="#99FFFFFF"/> <Controls:CircularProgressBar Value="30" Width="60" Height="90" ForeColor="#38baec"/> </StackPanel> </UniformGrid> </Grid> </Grid> </Grid> </UserControl>