WPF - 简单的UI框架 - 仪表盘
源码链接:https://github.com/DuelWithSelf/WPFEffects
参考:https://www.cnblogs.com/duel/p/duel_clock.html
更新一: 功能导览模块新增Binding用法示例。

更新二:仪表盘效果实现。

Binding用法与ListBox的用法一致:
Xaml定义节点样式; .cs 文件中定义数据:

<DataTemplate x:Key="ListMenuBox.ItemTemplate" DataType="{x:Type local:CatalogOfEffect}">
<Border x:Name="BdrNavItem" Background="Transparent" Height="30"
MouseLeftButtonUp="BdrNavItem_MouseLeftButtonUp">
<TextBlock Margin="60,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center"
Foreground="White" Text="{Binding Path=Name, Mode=TwoWay}"/>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected}" Value="True">
<Setter TargetName="BdrNavItem" Property="Background"
Value="{StaticResource ColorBrush.LightWhite}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>


public class BaseRecord : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string prop)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
} public class CatalogOfEffect: BaseRecord
{
private string _Name;
public string Name {
get { return _Name; }
set { _Name = value; this.OnPropertyChanged("Name"); }
} private bool _IsSelected;
public bool IsSelected
{
get { return _IsSelected; }
set { _IsSelected = value; this.OnPropertyChanged("IsSelected"); }
} private string _Key;
public string Key
{
get { return _Key; }
set { _Key = value; }
}
}

引用样式:
<CustomFrms:ListMenuBox
x:Name="LmxBinding" Text="Binding示例"
IconData="{StaticResource PathData.TagSolid}"
ItemTemplate="{StaticResource ListMenuBox.ItemTemplate}"/>
指定数据源:

ObservableCollection<CatalogOfEffect> ltCatalogs = new System.Collections.ObjectModel.ObservableCollection<CatalogOfEffect>();
ltCatalogs.Add(new CatalogOfEffect() { Name = "淡入动效", Key="AnimFadeIn" });
ltCatalogs.Add(new CatalogOfEffect() { Name = "淡出动效", Key = "AnimFadeOut" });
ltCatalogs.Add(new CatalogOfEffect() { Name = "翻转动效", Key = "AnimFlip" });
ltCatalogs.Add(new CatalogOfEffect() { Name = "爆炸动效", Key = "AnimExpo" });
this.LmxBinding.ItemsSource = ltCatalogs;

扇形画面有很多码农通过Path、 ArcSegment等方式去构建。 Blend里面有Arc。 官方封装好的直接拿来用,省心省力。 用Path和ArcSegment的方式去实现,无非是用自己的方式再封装出一个Arc,其实没必要。
仪表盘的实现原理请参考Github上的源码。
仪表盘:代码
<UserControl x:Class="WPFEffects.Modules.Chart.ClockChart.ClockSlave2View"
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:WPFEffects.Modules.Chart.ClockChart"
xmlns:BlendCom="http://schemas.microsoft.com/expression/2010/drawing"
mc:Ignorable="d" d:DesignHeight="480" d:DesignWidth="480">
<Grid Width="370" Height="370">
<BlendCom:Arc Width="340" Height="340" StartAngle="-136"
EndAngle="136" Stretch="None" ArcThickness="60">
<BlendCom:Arc.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#3300A2FF" Offset="0"/>
<GradientStop Color="#005ED3FF" Offset="1"/>
</LinearGradientBrush>
</BlendCom:Arc.Fill>
</BlendCom:Arc>
<Grid x:Name="GdEllipse" Width="290" Height="290">
<Rectangle Width="1" Height="8" VerticalAlignment="Top"
Fill="White" HorizontalAlignment="Center"
RenderTransformOrigin="0.5,18.05">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="2.7"/>
<TranslateTransform X="-0.5"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
<Grid x:Name="GdEllipse1" Width="306" Height="306">
<Rectangle Width="1" Height="16" VerticalAlignment="Top"
Fill="White" HorizontalAlignment="Center"
RenderTransformOrigin="0.5,9.53">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="0"/>
<TranslateTransform X="-0.5" Y="0"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Width="1" Height="16" VerticalAlignment="Top"
Fill="White" HorizontalAlignment="Center"
RenderTransformOrigin="0.5,9.53">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="67.5"/>
<TranslateTransform X="-0.5" Y="0"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Width="1" Height="16" VerticalAlignment="Top"
Fill="White" HorizontalAlignment="Center"
RenderTransformOrigin="0.5,9.53">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="135"/>
<TranslateTransform X="-0.5" Y="0"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Width="1" Height="16" VerticalAlignment="Top"
Fill="White" HorizontalAlignment="Center"
RenderTransformOrigin="0.5,9.53">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-67.5"/>
<TranslateTransform X="-0.5" Y="0"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Width="1" Height="16" VerticalAlignment="Top"
Fill="White" HorizontalAlignment="Center"
RenderTransformOrigin="0.5,9.53">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-135"/>
<TranslateTransform X="-0.5" Y="0"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
<Grid Width="270" Height="270">
<TextBlock Text="50" HorizontalAlignment="Center" VerticalAlignment="Top"
Foreground="White" FontSize="8" Margin="5"/>
<TextBlock Text="75" HorizontalAlignment="Right" VerticalAlignment="Top"
Foreground="White" FontSize="8" Margin="0,80,16,0"/>
<TextBlock Text="100" HorizontalAlignment="Right" VerticalAlignment="Bottom"
Foreground="White" FontSize="8" Margin="0,0,41,46"/>
<TextBlock Text="0" HorizontalAlignment="Left" VerticalAlignment="Bottom"
Foreground="White" FontSize="8" Margin="42,0,0,42"/>
<TextBlock Text="25" HorizontalAlignment="Left" VerticalAlignment="Top"
Foreground="White" FontSize="8" Margin="14,82,0,0"/>
</Grid>
<Grid Opacity="0">
<Grid Width="370" Height="370" x:Name="ClipProxy">
<Grid Background="Transparent"></Grid>
<BlendCom:Arc Width="370" Height="370" StartAngle="-180"
EndAngle="{Binding Path=DegreeAngle}" Fill="White"
x:Name="ArcProxy" Stretch="None"
ArcThickness="175" >
</BlendCom:Arc>
</Grid>
</Grid>
<Grid>
<Border Width="370" Height="370" Background="Transparent">
<Border.OpacityMask>
<VisualBrush Visual="{Binding ElementName=ClipProxy}"/>
</Border.OpacityMask>
<BlendCom:Arc Width="370" Height="370" StartAngle="-135"
EndAngle="135" Stretch="None" ArcThickness="10">
<BlendCom:Arc.Fill>
<LinearGradientBrush EndPoint="1,1" StartPoint="0,1">
<GradientStop Color="#FF31FF10" Offset="0.01"/>
<GradientStop Color="#FF760F0F" Offset="1"/>
<GradientStop Color="#FFE6BF6B" Offset="0.22"/>
<GradientStop Color="#FFF7876E" Offset="0.444"/>
<GradientStop Color="#FFE22E21" Offset="0.702"/>
</LinearGradientBrush>
</BlendCom:Arc.Fill>
</BlendCom:Arc>
</Border>
<Path Stretch="Fill" Width="4" Height="95" VerticalAlignment="Top"
Margin="0,90,0,0" HorizontalAlignment="Center"
Fill="#FF109B3A" Data="M0,180 L2,184 L4,180 L2 0 v4 z"
RenderTransformOrigin="0.5,0.946">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="{Binding Path=DegreeAngle}"/>
<TranslateTransform/>
</TransformGroup>
</Path.RenderTransform>
<Path.Effect>
<DropShadowEffect Color="White" Opacity="0.5" ShadowDepth="0" BlurRadius="8"/>
</Path.Effect>
</Path>
<TextBlock x:Name="TbkValue" Text="0.0" Foreground="White" HorizontalAlignment="Center"
VerticalAlignment="Bottom" Margin="0,0,0,130"/>
</Grid>
</Grid>
</UserControl>
---------------------------------------------------------------------------------------------------------------
public partial class ClockSlave2View : UserControl
{
public double DegreeAngle
{
get { return (double)base.GetValue(DegreeAngleProperty); }
set { base.SetValue(DegreeAngleProperty, value); }
}
public static readonly DependencyProperty DegreeAngleProperty =
DependencyProperty.Register("DegreeAngle", typeof(double), typeof(ClockSlave2View),
new FrameworkPropertyMetadata(0d));
public ClockSlave2View()
{
InitializeComponent();
this.CreateNormalBorderMark();
this.DataContext = this;
this.Loaded += ClockSlave2View_Loaded;
this.Unloaded += ClockSlave2View_Unloaded;
}
private void ClockSlave2View_Unloaded(object sender, RoutedEventArgs e)
{
this.FreeSampleTimer();
}
private void ClockSlave2View_Loaded(object sender, RoutedEventArgs e)
{
this.CreateSampleTimer();
}
private void CreateNormalBorderMark()
{
this.GdEllipse.Children.Clear();
double dAngel = 270d / 100d;
for (int i = 1; i <= 100; i++)
{
if (i % 25 != 0)
{
Rectangle rect = new Rectangle();
rect.VerticalAlignment = VerticalAlignment.Top;
rect.HorizontalAlignment = HorizontalAlignment.Center;
rect.Fill = new SolidColorBrush(Colors.White);
rect.Width = 1;
rect.Height = 8;
rect.RenderTransformOrigin = new Point(0.5, 18.05);
TransformGroup transGroup = new TransformGroup();
RotateTransform rotate = new RotateTransform();
rotate.Angle = -135 + i * dAngel;
transGroup.Children.Add(rotate);
TranslateTransform translate = new TranslateTransform();
translate.X = -0.5;
transGroup.Children.Add(translate);
rect.RenderTransform = transGroup;
this.GdEllipse.Children.Add(rect);
}
}
}
private DispatcherTimer TimerSample;
private void CreateSampleTimer()
{
if(this.TimerSample == null)
{
this.TimerSample = new DispatcherTimer();
this.TimerSample.Tick += TimerSample_Tick;
this.TimerSample.Interval = TimeSpan.FromSeconds(1);
}
this.TimerSample.Start();
}
private void FreeSampleTimer()
{
if(this.TimerSample != null)
{
this.TimerSample.Stop();
this.TimerSample.Tick -= TimerSample_Tick;
}
this.TimerSample = null;
}
private void TimerSample_Tick(object sender, EventArgs e)
{
Random random = new Random();
int nData = random.Next(0, 100);
this.TbkValue.Text = nData + "";
double dAngle = -135d + 270d * nData / 100d;
DoubleAnimation anim = new DoubleAnimation(dAngle, TimeSpan.FromSeconds(0.3));
anim.EasingFunction = new ExponentialEase();
this.BeginAnimation(DegreeAngleProperty, anim);
}
}
WPF - 简单的UI框架 - 仪表盘的更多相关文章
- WPF - 简单的UI框架
实现了一个简单的WPF应用程序UI框架 ,分享出来.界面效果图如下: 运行效果如下: 喜欢的可以下载源码参考:https://github.com/DuelWithSelf/WPFEffects 左侧 ...
- laya fgui 超简单的UI框架
FairyGUI 超简单的UI框架 Laya使用fgui的超简单UI框架 使用场景:用于使用fgui进行layaUI开发的程序人员 整个框架分为3个模块,共有4个类: FGUIManager :FGU ...
- 【设计和开发一套简单自己主动化UI框架】
!有兴趣的朋友请直接移步Github,本帖子已经不做更新,框架的详细的实现已经做了优化和代码整理,本文仅仅介绍了详细的设计思路! 目标:编写一个简单通用UI框架用于管理页面和完毕导航跳转 终于的实现效 ...
- 【转】发布一个基于NGUI编写的UI框架
发布一个基于NGUI编写的UI框架 1.加载,显示,隐藏,关闭页面,根据标示获得相应界面实例 2.提供界面显示隐藏动画接口 3.单独界面层级,Collider,背景管理 4.根据存储的导航信息完成界面 ...
- 造轮子,模仿WPF的UI框架,还没完善。。。
Wtf(暂时命名,随便起的 = _=),模仿WPF的框架,还没有完善,只有简单的基础元素,支持数据绑定.虽然支持mono但是mono有bug 写这个只是兴趣爱好,感觉也没多大意义了,如果这个UI框架完 ...
- WPF简单导航框架(Window与Page互相调用)
相当多的WPF程序都有着丰富的页面和功能,如何使程序在不同页面间转换并降低资源占用,选择适合自己的导航框架就很重要了.最近花了一点时间做了一个简单的导航框架,并在这个过程中对Window.Page.U ...
- (转载)基于Unity~UGUI的简单UI框架(附UIFramework源码)
此博客跟随siki老师的课程笔记生成,感谢siki老师的辛勤付出! 此框架功能较简单,适用于学习,可以很好的锻炼我们的设计思想 框架源码地址: UIFramework litjson.dll下载地址: ...
- 关于几种UI框架简单总结
最近两年多的时间先后做过几款终端程序,UI框架从MFC转向过WxWidgets,之后再转向Qt.三种框架精通远谈不上,用起来还是没什么问题. 简单聊聊三种框架的优缺点. 1.MFC 似乎作为一种饱受批 ...
- 免费UI框架推荐--Charisma UI
基于Jquery.Bootstrap的后台管理免费UI框架推荐--Charisma UI 在项目设计和开发工作中,做过一些后台管理系统的设计和开发,用的很多都是比较传统的UI框架. 老是走在这个圈子里 ...
随机推荐
- Gitbook配置目录折叠
如果有多个目录,Gitbook在浏览器上打开时,默认所有的目录都会打开,当目录比较多时,全部显示不利于阅读. 可以使用插件配置目录折叠,使得打开浏览器时这些目录默认是关闭的. 在执行gitbook i ...
- HTTP工作过程(浏览器输入URL到返回HTML页面都经历了什么)
超文本传送协议(HyperText Transport Protocol,HTTP)是互联网上应用最为广泛的一种网络协议,它工作在应用层,使用TCP的80号端口提供服务.并且HTTP是工作在客户/服务 ...
- C++ 标准模板库(STL)——迭代器(iterators)的用法及理解
C++ STL中迭代器(iterators)用于遍历对象集合的元素.由于容器大小随着插入删除等操作动态改变,无法像静态数组那样获取数组长度然后遍历容器里的所有元素:这时就需要迭代器,每次从容器内第一个 ...
- 【Azure Redis 缓存】云服务Worker Role中调用StackExchange.Redis,遇见莫名异常(RedisConnectionException: UnableToConnect on xxx 或 No connection is available to service this operation: xxx)
问题描述 在Visual Studio 2019中,通过Cloud Service模板创建了一个Worker Role的角色,在角色中使用StackExchange.Redis来连接Redis.遇见了 ...
- 【redis前传】redis整数集为什么不能降级
前言 整数集合相信有的同学没有听说过,因为redis对外提供的只有封装的五大对象!而我们本系列主旨是学习redis内部结构.内部结构是redis五大结构重要支撑! 前面我们分别从redis内部结构分析 ...
- 分布式ID生成器(CosId)的设计与实现
分布式ID生成器(CosId)设计与实现 CosId 简介 CosId 旨在提供通用.灵活.高性能的分布式 ID 生成器. 目前提供了俩类 ID 生成器: SnowflakeId : 单机 TPS 性 ...
- [HNOI2011]XOR和路径 题解
设 \(f(x)\) 表示从 \(x\) 节点走到 \(n\) 的期望.有 $$f(x)=\sum_{{x,y}}\frac{f(y)\oplus w(x,y)}{{\rm deg}(x)}$$ 由于 ...
- [POI2008]PER
很有思维的一道题 这个题的题面非常简单,出题人很友好,没有搞什么奇怪的背景,(卡农(P3214)的作者看看人家),所以理解题面就是: 一句话题意: 给定一个长度为 \(n\) 的数列,求这个数列是在其 ...
- CSS样式实现表头和列固定
效果图:第一行和第一列固定 <!DOCTYPE html> <html lang="zh"> <head> <meta cha ...
- Python自动化测试面试题-Linux篇
目录 Python自动化测试面试题-经验篇 Python自动化测试面试题-用例设计篇 Python自动化测试面试题-Linux篇 Python自动化测试面试题-MySQL篇 Python自动化测试面试 ...