分享初学者的第一个WPF应用程序——Timer线程时时刷新当前系统时间赋值于相关属性,并将其值绑定于TextBlock的Text属性...


这个例子嘛是源于《WPF专业编程指南》(李应保著),这是我学习WPF以来看到第一个比较具体的例子,也是我在VS开发环境中写的第一个例子,感觉这个例子不错(当然书中还有几处错误)、能把好多知识点都连贯起来,所以献丑与大家分享一下,哈哈…

先看一下效果图吧:
2010091308441733.png
接下来看看XAML中代码吧,挺少的,因为界面也挺简单的

ContractedBlock.gif ExpandedBlockStart.gif XAML部分代码
 
   
< Window x:Class ="TimeWPF.TimeWindow"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local
="clr-namespace:TimeWPF"
Title
="我的第一个WPF应用程序——获取当前时间" Height ="350" Width ="525" >
< StackPanel >
< local:MyTextBlock Text =" {Binding RelativeSource={x:Static Member=RelativeSource.Self},Path=Time} " FontSize ="32" Background ="Wheat" />

< local:MyTextBlock Text =" {Binding RelativeSource={x:Static Member=RelativeSource.Self},Path=Time} " Time ="2010/09/30" FontSize ="20" Background ="White" />

</ StackPanel >
</ Window >

 

上一部分代码呢,用到了数据绑定,由于对数据绑定的语法还不熟悉、弄了好长时间才弄出来。


下面嘛,毫无疑问了肯定是C#部分的代码了,如果你注意到了MyBlockText,那么你应该想到了这里的C#部分代码至少是两个类:一个是与XAML有关联的partial类,还有一个自定义类、它扩展了BlockText。

ContractedBlock.gif ExpandedBlockStart.gif partial 类部分代码
 
   
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;

namespace TimeWPF
{
///
< summary >
/// MainWindow.xaml 的交互逻辑
///
</ summary >
public partial class TimeWindow : Window
{
///
< summary >
/// 声明一个委托用于新线程中使用它 去设定当前的系统时间
///
</ summary >
///
< param name ="dt" ></ param >
private delegate void SetTimeDelegate(DateTime dt);

///
< summary >
/// 计时器
///
</ summary >
private Timer myTimer;

///
< summary >
/// 声明一个相关属性
///
</ summary >
public static DependencyProperty TimeProperty;

///
< summary >
/// 静态够造函数
///
</ summary >
static TimeWindow()
{
//实例化一个 属性与元数据间的关系实体
FrameworkPropertyMetadata meta = new FrameworkPropertyMetadata();

meta.Inherits = true; //标记依赖属性项是否可以被传递下去
meta.AffectsMeasure = true; //标记该属性可以影响布局
meta.DefaultValue = DateTime.Now;//设置默认值
meta.PropertyChangedCallback += new PropertyChangedCallback(OnTimePropertyChanged);

//注册一个可读可写的相关属性
TimeProperty = DependencyProperty.Register("Time",typeof(DateTime),typeof(TimeWindow),meta,new ValidateValueCallback(ValidateTimeProperty));
}

///
< summary >
/// 回调 验证方法
///
</ summary >
///
< param name ="obj" > 传入当前要被验证的属性值 </ param >
///
< returns > 返回验证结果 </ returns >
public static bool ValidateTimeProperty(object obj)
{
DateTime dt = (DateTime)obj;

if (dt.Year
< 2020 && dt.Year > 1990)
{
return true;
}
else
{
return false;
}
}

///
< summary >
/// 属性值发生改变
///
</ summary >
///
< param name ="sender" ></ param >
///
< param name ="args" ></ param >
public static void OnTimePropertyChanged(DependencyObject sender,DependencyPropertyChangedEventArgs args)
{

}

/ 定义一个CLR属性
/
</ summary >
//public DateTime Time
//{
// set { SetValue(TimeProperty,value);}
// get { return (DateTime)GetValue(TimeProperty); }
//}

///
< summary >
/// 构造函数
///
</ summary >
public TimeWindow()
{
InitializeComponent();

//启动新线程刷新相关属性 TimeProperty
myTimer = new Timer(new TimerCallback(RefreshTime), new AutoResetEvent(false), 0, 1000);//立即启动 每1000毫秒调用一次CallBack
}

///
< summary >
/// Timer CallBack 函数用于刷新当前的TimeProperty相关属性的属性值
///
</ summary >
///
< param name ="obj" ></ param >
private void RefreshTime(object stateInfo)
{
SetTimeDelegate d = new SetTimeDelegate(this.SetTime);

this.Dispatcher.BeginInvoke(d, System.Windows.Threading.DispatcherPriority.Send, DateTime.Now);

}

///
< summary >
/// 用当前时间 设置相关属性TimeProperty的值
///
</ summary >
///
< param name ="dt" ></ param >
private void SetTime(DateTime dt)
{
//this.Time = dt;
SetValue(TimeProperty, dt);
}

}
}

 

 

ContractedBlock.gif ExpandedBlockStart.gif 自定义类扩展BlockText代码
 
   
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Threading;


namespace TimeWPF
{
///
< summary >
/// 自定义TextBlock
///
</ summary >
public class MyTextBlock :TextBlock
{
///
< summary >
/// 声明一个相关属性
///
</ summary >
public static DependencyProperty TimeProperty;

///
< summary >
/// 静态构造函数
///
</ summary >
static MyTextBlock()
{
//实例化一个属性与元数据间的关系
FrameworkPropertyMetadata meta = new FrameworkPropertyMetadata();
meta.Inherits = true;

//将另一类型 作为 已经注册的 依赖属性的所有者来添加
TimeProperty = TimeWindow.TimeProperty.AddOwner(typeof(MyTextBlock));

//重写特定类型上的元数据
TimeProperty.OverrideMetadata(typeof(MyTextBlock), meta);
}


public MyTextBlock() :base()
{

}

///
< summary >
/// MyTextBlock.TimeProperty
/// CLR属性
///
</ summary >
public DateTime Time
{
set { SetValue(TimeProperty, value); }
get { return (DateTime)GetValue(TimeProperty); }
}

}
}

 

好了,代码大概就这些了,下面再写一些于之相关的东东吧。
(1)WPF应用程序提供了8个提供程序用于设置依赖属性的值它们的优先级从高到底依次为:
      1、本地值;2、样式触发器;3、模板触发器;4、样式设置程序;5、主题样式设置程序;6、主题样式设置程序;7属性值传递;8、默认值;

(2) 改天关注一下数据绑定语法。

 

呵呵…… 都没有注意到时间九点了啊,该工作了、改天继续……

 

 

 




 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值