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应用程序?
 
