WPF 构建无外观(Lookless)控件
原文:
WPF 构建无外观(Lookless)控件
构建一个用户可以使用Template属性设置外观的WPF控件需要以下几步
?我们的自定义控件继承自System.Windows.Controls.Control,如果有更特别的控件,也可以继承自更复杂的控件。 类声明 1: public class Clock : Control 2: {
3: }
? 第2步 设置DefaultStyleKeyProperty?无外观的控件需要在静态构造函数中设置DefaultStyleKeyProperty,这样它会去在themes/generic.xaml的文件获取默认的样式。 1: static Clock()
3: DefaultStyleKeyProperty.OverrideMetadata(typeof(Clock),new FrameworkPropertyMetadata(typeof(Clock))); 4: }
第3步 实现控件功能这一步没什么特别的,就是内部有个DateTime类型和一个DispatcherTimer,完成一个时钟的功能 3: private DispatcherTimer timer;
4:?
5: static Clock() 6: {
7: DefaultStyleKeyProperty.OverrideMetadata(typeof(Clock),monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 12pt; overflow: visible; padding-top: 0px"> 8: } 9:?
10: protected override void OnInitialized(EventArgs e) 11: {
12: base.OnInitialized(e); 13:?
14: UpdateDateTime();
15:?
16: timer = new DispatcherTimer(); 17: timer.Interval = TimeSpan.FromMilliseconds(1000 - DateTime.Now.Millisecond);
18: timer.Tick += new EventHandler(Timer_Tick); 19: timer.Start();
20: }
21:?
22: private void Timer_Tick(object sender,EventArgs e) 23: {
24: UpdateDateTime();
25:?
26: timer.Interval = TimeSpan.FromMilliseconds(1000 - DateTime.Now.Millisecond);
27: timer.Start();
28: }
29:?
30: private void UpdateDateTime() 31: {
32: this.DateTime = System.DateTime.Now; 33: }
34:?
35: public DateTime DateTime 36: {
37: get
38: {
39: return (DateTime)GetValue(DateTimeProperty); 40: }
41: private set 42: {
43: SetValue(DateTimeProperty,value); 44: }
45: }
46:?
47: public static DependencyProperty DateTimeProperty = DependencyProperty.Register( 48: "DateTime", 49: typeof(DateTime), 50: typeof(Clock),monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 12pt; overflow: visible; padding-top: 0px"> 51: new PropertyMetadata(DateTime.Now,new PropertyChangedCallback(OnDateTimeInvalidated))); 52:?
53: public static readonly RoutedEvent DateTimeChangedEvent = 54: EventManager.RegisterRoutedEvent("DateTimeChanged",RoutingStrategy.Bubble,typeof(RoutedPropertyChangedEventHandler<DateTime>),typeof(Clock)); 55:?
56: protected virtual void OnDateTimeChanged(DateTime oldValue,DateTime newValue) 57: {
58: RoutedPropertyChangedEventArgs<DateTime> args = new RoutedPropertyChangedEventArgs<DateTime>(oldValue,newValue); 59: args.RoutedEvent = Clock.DateTimeChangedEvent;
60: RaiseEvent(args);
61: }
62:?
63: private static void OnDateTimeInvalidated(DependencyObject d,DependencyPropertyChangedEventArgs e) 64: {
65: Clock clock = (Clock)d;
66:?
67: DateTime oldValue = (DateTime)e.OldValue;
68: DateTime newValue = (DateTime)e.NewValue;
69:?
70: clock.OnDateTimeChanged(oldValue,monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 12pt; overflow: visible; padding-top: 0px"> 71: } 72: }
? 第4步 定义默认Sytle?如上所述,我们还需要一个默认的Template,它写在themes/generic.xaml文件中,这个文件可能需要自己创建 1: <ResourceDictionary
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4: xmlns:local="clr-namespace:CustomControlLibrary" 5: > 6:?
7: <Style TargetType="{x:Type local:Clock}"> 8: <Setter Property="Template"> 9: <Setter.Value> 10: <ControlTemplate TargetType="{x:Type local:Clock}"> 11: <TextBlock Text="{Binding Path=DateTime,RelativeSource={RelativeSource TemplatedParent}}" /> 12: </ControlTemplate> 13: </Setter.Value> 14: </Setter> 15: </Style> 16: </ResourceDictionary> ?
?最后还需要在AssemblyInfo.cs文件中加入ThemeInfo信息,在文件中加入以下特性 1: [assembly: ThemeInfo(
2: ResourceDictionaryLocation.None,monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 12pt; overflow: visible; padding-top: 0px"> 3: ResourceDictionaryLocation.SourceAssembly 4: )]
?
?如果需要在模板中使用特定的元素名,来或许模板中的某个特定控件,还有几个地方需要注意。 1、模板内的Name最好以PART开头,好的名称类似于PART_TextBox 2、获取Template中控件的代码,需要重载OnApplyTemplate()方法,可以使用GetTemplateChild方法获取,如下 1: public override void OnApplyTemplate()
3: base.OnApplyTemplate(); 5: //从模板中获取名称为PART_PresentationTextBox的TextBox 6: _presentationTextBox = GetTemplateChild("PART_PresentationTextBox") as TextBox; 7: if(_presentationTextBox != null) 8: {
9: //对_presentationTextBox进行操作 10: }
11: }
3、在控件类添加TemplatePart 1: [TemplatePart(Name = "PART_PresentationTextBox",Type = typeof(TextBox))]
2: public class TimeSpanPicker:Control 这个内容可以参考https://gitcafe.com/atskyline/WPFTimeSpanPickerControl
?http://www.codeproject.com/Articles/14340/Creating-a-look-less-custom-control-in-WPF http://www.codeproject.com/Articles/35444/Defining-the-Default-Style-for-a-Lookless-Control (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- ms-project – 如何强制Microsoft Project中的任
- windows-server-2008 – 如何通过电子邮件发送预
- 在DLL中捕获C#中的SOAP
- windows-server-2008 – 如果/ bin更改,我可以阻
- windows – 如何在Visual Studio代码上删除最近打
- windows-server-2008 – 在Windows 2008上的卷之
- iis – 我可以配置Windows主机文件以使用IP地址和
- windows – 从ReplaceFile重现ERROR_UNABLE_TO_M
- windows – 将exec’d批处理文件中的退出代码传播
- windows-phone-7 – 以编程方式关闭WP7应用程序?