源码链接: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框架 - 仪表盘的更多相关文章

  1. WPF - 简单的UI框架

    实现了一个简单的WPF应用程序UI框架 ,分享出来.界面效果图如下: 运行效果如下: 喜欢的可以下载源码参考:https://github.com/DuelWithSelf/WPFEffects 左侧 ...

  2. laya fgui 超简单的UI框架

    FairyGUI 超简单的UI框架 Laya使用fgui的超简单UI框架 使用场景:用于使用fgui进行layaUI开发的程序人员 整个框架分为3个模块,共有4个类: FGUIManager :FGU ...

  3. 【设计和开发一套简单自己主动化UI框架】

    !有兴趣的朋友请直接移步Github,本帖子已经不做更新,框架的详细的实现已经做了优化和代码整理,本文仅仅介绍了详细的设计思路! 目标:编写一个简单通用UI框架用于管理页面和完毕导航跳转 终于的实现效 ...

  4. 【转】发布一个基于NGUI编写的UI框架

    发布一个基于NGUI编写的UI框架 1.加载,显示,隐藏,关闭页面,根据标示获得相应界面实例 2.提供界面显示隐藏动画接口 3.单独界面层级,Collider,背景管理 4.根据存储的导航信息完成界面 ...

  5. 造轮子,模仿WPF的UI框架,还没完善。。。

    Wtf(暂时命名,随便起的 = _=),模仿WPF的框架,还没有完善,只有简单的基础元素,支持数据绑定.虽然支持mono但是mono有bug 写这个只是兴趣爱好,感觉也没多大意义了,如果这个UI框架完 ...

  6. WPF简单导航框架(Window与Page互相调用)

    相当多的WPF程序都有着丰富的页面和功能,如何使程序在不同页面间转换并降低资源占用,选择适合自己的导航框架就很重要了.最近花了一点时间做了一个简单的导航框架,并在这个过程中对Window.Page.U ...

  7. (转载)基于Unity~UGUI的简单UI框架(附UIFramework源码)

    此博客跟随siki老师的课程笔记生成,感谢siki老师的辛勤付出! 此框架功能较简单,适用于学习,可以很好的锻炼我们的设计思想 框架源码地址: UIFramework litjson.dll下载地址: ...

  8. 关于几种UI框架简单总结

    最近两年多的时间先后做过几款终端程序,UI框架从MFC转向过WxWidgets,之后再转向Qt.三种框架精通远谈不上,用起来还是没什么问题. 简单聊聊三种框架的优缺点. 1.MFC 似乎作为一种饱受批 ...

  9. 免费UI框架推荐--Charisma UI

    基于Jquery.Bootstrap的后台管理免费UI框架推荐--Charisma UI 在项目设计和开发工作中,做过一些后台管理系统的设计和开发,用的很多都是比较传统的UI框架. 老是走在这个圈子里 ...

随机推荐

  1. Kubernetes全栈架构师(二进制高可用安装k8s集群部署篇)--学习笔记

    目录 二进制高可用基本配置 二进制系统和内核升级 二进制基本组件安装 二进制生成证书详解 二进制高可用及etcd配置 二进制K8s组件配置 二进制使用Bootstrapping自动颁发证书 二进制No ...

  2. C语言:猴子吃桃问题

    //猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个. //第二天早上又将第一天剩下的桃子吃掉一半,有多吃了一个.以后每天早上都吃了前一天剩下的一半零一个. //到第 10 ...

  3. OSPF的基本工作原理

    OSPF的基本工作原理 1.定义 2.特点 3.基本概念 4.OSPF五种分组类型 5.DR/BDR 6.区域 1.定义 开放最短路径优先OSPF,是为了克服RIP的缺点在1989年开发出来的. &q ...

  4. ES6新增语法(四)——面向对象

    ES6中json的2个变化 简写:名字和值相同时,json可以可以简写 let a=12,b=5; let json = { a, b } console.log(json) // { a:12 , ...

  5. 接入 SDK 结果翻车了?了解 SDK 的那些事

    前段时间,二狗子的朋友圈被工信部发布的<关于下架侵害用户权益 App 名单的通报>给刷屏了.公告中指出有 90 款 App 未按照要求完成整改将会下架.而这 90 款 App 涉及全国各地 ...

  6. ES6 数组Arrary 常用方法

    ES6 数组Arrary 常用方法: <script type="text/javascript"> // 操作数据方法 // arr.push() 从后面添加元素,返 ...

  7. 常用的jquery加载后执行的写法

    (function(doc){ })(document); $(function(){ }) jQuery(function(){ }) $(document).ready(function(){ } ...

  8. 使用vue-preview报错Cannot read property 'open' of undefined

    最近在做一个vue项目中时,需要使用vue-preview插件制作缩略图,首先在终端使用npm i vue-preview -S指令安装了vue-preview插件,然后在main.js中,导入并引用 ...

  9. etcd学习(4)-centos7中部署etcd

    etcd的搭建 前言 单机 集群 创建etcd配置文件 更新etcd系统默认配置 启动 配置ETCD为启动服务 测试下 参考 etcd的搭建 前言 这里记录下如何搭建etcd 单机 在etcd的rel ...

  10. odoo接口跨域问题

    odoo Controller接口开发 POST请求的跨域问题解决方法 1.odoo Controller接口开发,前端在请求的时候会发生跨域问题,报错信息如下:Function declared a ...