当前位置: 首页 > news >正文

苏州做网站公有哪些外贸公司网站做的比较好

苏州做网站公,有哪些外贸公司网站做的比较好,网页设计报告论文,做进口产品的网站好一、引言 感觉最近都颓废了#xff0c;好久没有学习写博文了#xff0c;出于负罪感#xff0c;今天强烈逼迫自己开始更新WPF系列。尽管最近看到一篇WPF技术是否老矣的文章#xff0c;但是还是不能阻止我系统学习WPF。今天继续分享WPF中一个最重要的知识点——依赖属性。 二… 一、引言   感觉最近都颓废了好久没有学习写博文了出于负罪感今天强烈逼迫自己开始更新WPF系列。尽管最近看到一篇WPF技术是否老矣的文章但是还是不能阻止我系统学习WPF。今天继续分享WPF中一个最重要的知识点——依赖属性。 二、依赖属性的全面解析   听到依赖属性自然联想到C#中属性的概念。C#中属性是抽象模型的核心部分而依赖属性是专门基于WPF创建的。在WPF库实现中依赖属性使用普通的C#属性进行了包装使得我们可以通过和以前一样的方式来使用依赖属性但我们必须明确在WPF中我们大多数都在使用依赖属性而不是使用属性。依赖属性重要性在于在WPF核心特性如动画、数据绑定以及样式中都需要使用到依赖属性。既然WPF引入了依赖属性也自然有其引入的道理。WPF中的依赖属性主要有以下三个优点 依赖属性加入了属性变化通知、限制、验证等功能。这样可以使我们更方便地实现应用同时大大减少了代码量。许多之前需要写很多代码才能实现的功能在WPF中可以轻松实现。节约内存在WinForm中每个UI控件的属性都赋予了初始值这样每个相同的控件在内存中都会保存一份初始值。而WPF依赖属性很好地解决了这个问题它内部实现使用哈希表存储机制对多个相同控件的相同属性的值都只保存一份。关于依赖属性如何节约内存的更多内容参考WPF的依赖属性是怎么节约内存的支持多种提供对象可以通过多种方式来设置依赖属性的值。可以配合表达式、样式和绑定来对依赖属性设置值。2.1 依赖属性的定义   上面介绍了依赖属性所带来的好处这时候问题又来了怎样自己定义一个依赖属性呢C#属性的定义大家再熟悉不过了。下面通过把C#属性进行改写成依赖属性的方式来介绍依赖属性的定义。下面是一个属性的定义 1 public class Person 2 { 3 public string Name { get; set; } 6 }   在把上面属性改写为依赖属性之前下面总结下定义依赖属性的步骤 让依赖属性的所在类型继承自DependencyObject类。使用public static 声明一个DependencyProperty的变量该变量就是真正的依赖属性。在类型的静态构造函数中通过Register方法完成依赖属性的元数据注册。提供一个依赖属性的包装属性通过这个属性来完成对依赖属性的读写操作。  根据上面的四个步骤下面来把Name属性来改写成一个依赖属性具体的实现代码如下所示 // 1. 使类型继承DependencyObject类public class Person : DependencyObject{// 2. 声明一个静态只读的DependencyProperty 字段public static readonly DependencyProperty nameProperty;static Person(){// 3. 注册定义的依赖属性nameProperty DependencyProperty.Register(Name, typeof(string), typeof(Person), new PropertyMetadata(Learning Hard,OnValueChanged)); }// 4. 属性包装器通过它来读取和设置我们刚才注册的依赖属性public string Name{get { return (string)GetValue(nameProperty); }set { SetValue(nameProperty, value); }}private static void OnValueChanged(DependencyObject dpobj, DependencyPropertyChangedEventArgs e){// 当只发生改变时回调的方法}}   从上面代码可以看出依赖属性是通过调用DependencyObject的GetValue和SetValue来对依赖属性进行读写的。它使用哈希表来进行存储的对应的Key就是属性的HashCode值而值Value则是注册的DependencyPropery而C#中的属性是类私有字段的封装可以通过对该字段进行操作来对属性进行读写。总结为属性是字段的包装WPF中使用属性对依赖属性进行包装。 2.2 依赖属性的优先级    WPF允许在多个地方设置依赖属性的值则自然就涉及到依赖属性获取值的优先级问题。例如下面XMAL代码我们在三个地方设置了按钮的背景颜色那最终按钮会读取那个设置的值呢是Green、Yellow还是Red Window x:ClassDPSample.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlTitleMainWindow Height350 Width525GridButton x:NamemyButton BackgroundGreen Width100 Height30Button.StyleStyle TargetType{x:Type Button}Setter PropertyBackground ValueYellow/Style.TriggersTrigger PropertyIsMouseOver ValueTrueSetter PropertyBackground ValueRed //Trigger/Style.Triggers/Style/Button.StyleClick Me /Button/Grid /Window   上面按钮的背景颜色是Green。之所以背景色是Green是因为WPF每访问一个依赖属性它都会按照下面的顺序由高到底处理该值。具体优先级如下图所示   在上面XAML中按钮的本地值设置的是Green自定义Style Trigger设置的为Red自定义的Style Setter设置的为Yellow由于这里的本地值的优先级最高所以按钮的背景色或者的是Green值。如果此时把本地值Green去掉的话此时按钮的背景颜色是Yellow而不是Red。这里尽管Style Trigger的优先级比Style Setter高但是由于此时Style Trigger的IsMouseOver属性为false即鼠标没有移到按钮上一旦鼠标移到按钮上时此时按钮的颜色就为Red。此时才会体现出Style Trigger的优先级比Style Setter优先级高。所以上图中优先级是比较理想情况下很多时候还需要具体分析。 2.3 依赖属性的继承   依赖属性是可以被继承的即父元素的相关设置会自动传递给所有的子元素。下面代码演示了依赖属性的继承。 Window x:ClassCustom_DPInherited.DPInheritedxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006 xmlns:dhttp://schemas.microsoft.com/expression/blend/2008 mc:Ignorabled d:DesignHeight300 d:DesignWidth300FontSize18Title依赖属性的继承StackPanel Label Content继承自Window的FontSize /Label Content显式设置FontSize TextElement.FontSize36/StatusBarStatusbar没有继承自Window的FontSize/StatusBar/StackPanel /Window 上面的代码的运行效果如下图所示   在上面XAML代码中。Window.FontSize设置会影响所有内部子元素字体大小这就是依赖属性的继承。如第一个Label没有定义FontSize所以它继承了Window.FontSize值。但一旦子元素提供了显式设置这种继承就会被打断所以Window.FontSize值对于第二个Label不再起作用。   这时你可能已经发现了问题StatusBar没有显式设置FontSize值但它的字体大小没有继承Window.FontSize的值而是保持了系统的默认值。那这是什么原因呢其实导致这样的问题并不是所有元素都支持属性值继承的如StatusBar、Tooptip和Menu控件。另外StatusBar等控件截获了从父元素继承来的属性并且该属性也不会影响StatusBar控件的子元素。例如如果我们在StatusBar中添加一个Button。那么这个Button的FontSize属性也不会发生改变其值为默认值。   前面介绍了依赖属性的继承那我们如何把自定义的依赖属性设置为可被其他控件继承呢通过AddOwer方法可以依赖属性的继承。具体的实现代码如下所示 1 public class CustomStackPanel : StackPanel2 {3 public static readonly DependencyProperty MinDateProperty;4 5 static CustomStackPanel()6 {7 MinDateProperty DependencyProperty.Register(MinDate, typeof(DateTime), typeof(CustomStackPanel), new FrameworkPropertyMetadata(DateTime.MinValue, FrameworkPropertyMetadataOptions.Inherits));8 }9 10 public DateTime MinDate 11 { 12 get { return (DateTime)GetValue(MinDateProperty); } 13 set { SetValue(MinDateProperty, value); } 14 } 15 } 16 17 public class CustomButton :Button 18 { 19 private static readonly DependencyProperty MinDateProperty; 20 21 static CustomButton() 22 { 23 // AddOwner方法指定依赖属性的所有者从而实现依赖属性的继承即CustomStackPanel的MinDate属性被CustomButton控件继承。 24 // 注意FrameworkPropertyMetadataOptions的值为Inherits 25 MinDateProperty CustomStackPanel.MinDateProperty.AddOwner(typeof(CustomButton), new FrameworkPropertyMetadata(DateTime.MinValue, FrameworkPropertyMetadataOptions.Inherits)); 26 } 27 28 public DateTime MinDate 29 { 30 get { return (DateTime)GetValue(MinDateProperty); } 31 set { SetValue(MinDateProperty, value); } 32 } 33 }   接下来你可以在XAML中进行测试使用具体的XAML代码如下 Window x:ClassCustom_DPInherited.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:localclr-namespace:Custom_DPInheritedxmlns:sysclr-namespace:System;assemblymscorlibTitle实现自定义依赖属性的继承 Height350 Width525Gridlocal:CustomStackPanel x:NamecustomStackPanle MinDate{x:Static sys:DateTime.Now}!--CustomStackPanel的依赖属性--ContentPresenter Content{Binding PathMinDate, ElementNamecustomStackPanle}/local:CustomButton Content{Binding RelativeSource{x:Static RelativeSource.Self}, PathMinDate} Height25//local:CustomStackPanel/Grid /Window   上面XAML代码中显示设置了CustomStackPanel的MinDate的值而在CustomButton中却没有显式设置其MinDate值。CustomButton的Content属性的值是通过绑定MinDate属性来进行获取的关于绑定的更多内容会在后面文章中分享。在这里CustomButton中并没有设置MinDate的值但是CustomButton的Content的值却是当前的时间从而可以看出此时CustomButton的MinDate属性继承了CustomStackPanel的MinDate的值从而设置了其Content属性。最终的效果如下图所示 2.4 只读依赖属性    在C#属性中我们可以通过设置只读属性来防止外界恶意更改该属性值同样在WPF中也可以设置只读依赖属性。如IsMouseOver就是一个只读依赖属性。那我们如何创建一个只读依赖属性呢其实只读的依赖属性的定义方式与一般依赖属性的定义方式基本一样。只读依赖属性仅仅是用DependencyProperty.RegisterReadonly替换了DependencyProperty.Register而已。下面代码实现了一个只读依赖属性。 1 public partial class MainWindow : Window2 {3 public MainWindow()4 {5 InitializeComponent();6 7 // 内部使用SetValue来设置值8 SetValue(counterKey, 8);9 } 10 11 // 属性包装器只提供GetValue你也可以设置一个private的SetValue进行限制。 12 public int Counter 13 { 14 get { return (int)GetValue(counterKey.DependencyProperty); } 15 } 16 17 // 使用RegisterReadOnly来代替Register来注册一个只读的依赖属性 18 private static readonly DependencyPropertyKey counterKey 19 DependencyProperty.RegisterReadOnly(Counter, 20 typeof(int), 21 typeof(MainWindow), 22 new PropertyMetadata(0)); 23 }   对应的XAML代码为 Window x:ClassReadOnlyDP.MainWindow NameThisWinxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlTitleReadOnly Dependency Property Height350 Width525GridViewboxTextBlock Text{Binding ElementNameThisWin, PathCounter}//Viewbox/Grid /Window   此时Counter包装的counterKey就是一个只读依赖属性因为其定义为private的所以在类外也不能使用DependencyObject.SetValue方法来对其值而包装的Counter属性又只提供了GetValue方法所以类外部只能对该依赖属性进行读取而不能对其赋值。此时运行效果如下图所示。 2.5 附加属性   WPF中还有一类特殊的属性——附加属性。附加是一种特殊的依赖属性。它允许给一个对象添加一个值而该对象可能对这个值一无所知。附加属性最常见的例子就是布局容器中DockPanel类中的Dock附加属性和Grid类中Row和Column附加属性。那问题又来了我们怎样在自己的类中定义一个附加属性呢其实定义附加属性和定义一般的依赖属性一样没什么区别只是用RegisterAttached方法代替了Register方法罢了。下面代码演示了附加属性的定义。 public class AttachedPropertyClass{// 通过使用RegisterAttached来注册一个附加属性public static readonly DependencyProperty IsAttachedProperty DependencyProperty.RegisterAttached(IsAttached, typeof(bool), typeof(AttachedPropertyClass),new FrameworkPropertyMetadata((bool)false));// 通过静态方法的形式暴露读的操作public static bool GetIsAttached(DependencyObject dpo){return (bool)dpo.GetValue(IsAttachedProperty);}public static void SetIsAttached(DependencyObject dpo, bool value){dpo.SetValue(IsAttachedProperty, value);}}   在上面代码中IsAttached就是一个附加属性附加属性没有采用CLR属性进行封装而是使用静态SetIsAttached方法和GetIsAttached方法来存取IsAttached值。这两个静态方法内部一样是调用SetValue和GetValue来对附加属性读写的。 2.6 依赖属性验证和强制    在定义任何类型的属性时都需要考虑错误设置属性的可能性。对于传统的CLR属性可以在属性的设置器中进行属性值的验证不满足条件的值可以抛出异常。但对于依赖属性来说这种方法不合适因为依赖属性通过SetValue方法来直接设置其值的。然而WPF有其代替的方式WPF中提供了两种方法来用于验证依赖属性的值。 ValidateValueCallback:该回调函数可以接受或拒绝新值。该值可作为DependencyProperty.Register方法的一个参数。CoerceValueCallback:该回调函数可将新值强制修改为可被接受的值。例如某个依赖属性Age的值范围是0到120在该回调函数中可以对设置的值进行强制修改对于不满足条件的值强制修改为满足条件的值。如当设置为负值时可强制修改为0。该回调函数可作为PropertyMetadata构造函数参数进行传递。  当应用程序设置一个依赖属性时所涉及的验证过程如下所示 首先CoerceValueCallback方法可以修改提供的值或返回DependencyProperty.UnsetValue。如果CoerceValueCallback方法强制修改了提供的值此时会激活ValidateValueCallback方法进行验证如果该方法返回为true表示该值合法被认为可被接受的否则拒绝该值。不像CoerceValueCallback方法ValidateValueCallback方法不能访问设置属性的实际对象这意味着你不能检查其他属性值。即该方法中不能对类的其他属性值进行访问。如果上面两个阶段都成功的话最后会触发PropertyChangedCallback方法来触发依赖属性值的更改。  下面代码演示了基本的流程。 1 class Program2 {3 static void Main(string[] args)4 {5 SimpleDPClass sDPClass new SimpleDPClass();6 sDPClass.SimpleDP 2;7 Console.ReadLine();8 }9 } 10 11 public class SimpleDPClass : DependencyObject 12 { 13 public static readonly DependencyProperty SimpleDPProperty 14 DependencyProperty.Register(SimpleDP, typeof(double), typeof(SimpleDPClass), 15 new FrameworkPropertyMetadata((double)0.0, 16 FrameworkPropertyMetadataOptions.None, 17 new PropertyChangedCallback(OnValueChanged), 18 new CoerceValueCallback(CoerceValue)), 19 new ValidateValueCallback(IsValidValue)); 20 21 public double SimpleDP 22 { 23 get { return (double)GetValue(SimpleDPProperty); } 24 set { SetValue(SimpleDPProperty, value); } 25 } 26 27 private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 28 { 29 Console.WriteLine(当值改变时我们可以做的一些操作具体可以在这里定义 {0}, e.NewValue); 30 } 31 32 private static object CoerceValue(DependencyObject d, object value) 33 { 34 Console.WriteLine(对值进行限定强制值 {0}, value); 35 return value; 36 } 37 38 private static bool IsValidValue(object value) 39 { 40 Console.WriteLine(验证值是否通过返回bool值如果返回True表示验证通过否则会以异常的形式暴露 {0}, value); 41 return true; 42 } 43 }   其运行结果如下图所示   从运行结果可以看出此时并没有按照上面的流程先Coerce后Validate的顺序执行这可能是WPF内部做了一些特殊的处理。当属性被改变时首先会调用Validate来判断传入的value是否有效如果无效就不继续后续操作。并且CoerceValue后面并没有运行ValidateValue而是直接调用PropertyChanged。这是因为CoerceValue操作并没有强制改变属性的值而前面对这个值已经验证过了所以也就没有必要再运行Valudate方法来进行验证了。但是如果在Coerce中改变了Value的值那么还会再次调用Valudate操作来验证值是否合法。 2.7  依赖属性的监听   我们可以用两种方法对依赖属性的改变进行监听。这两种方法是 使用DependencyPropertyDescriptor类使用OverrideMetadata的方式。  下面分别使用这两种方式来实现下对依赖属性的监听。   第一种方式定义一个派生于依赖属性所在的类然后重写依赖属性的元数据并传递一个PropertyChangedCallback参数即可具体的实现如下代码所示 1 public class MyTextBox : TextBox2 {3 public MyTextBox()4 : base()5 {6 }7 8 static MyTextBox()9 { 10 //第一种方法通过OverrideMetadata 11 TextProperty.OverrideMetadata(typeof(MyTextBox), new FrameworkPropertyMetadata(new PropertyChangedCallback(TextPropertyChanged))); 12 } 13 14 private static void TextPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) 15 { 16 MessageBox.Show(, Changed); 17 } 18 }   第二种方法这个方法更加简单获取DependencyPropertyDescriptor并调用AddValueChange方法为其绑定一个回调函数。具体实现代码如下所示 public MainWindow(){InitializeComponent();//第二种方法通过OverrideMetadataDependencyPropertyDescriptor descriptor DependencyPropertyDescriptor.FromProperty(TextBox.TextProperty, typeof(TextBox));descriptor.AddValueChanged(tbxEditMe, tbxEditMe_TextChanged);}private void tbxEditMe_TextChanged(object sender, EventArgs e){MessageBox.Show(, Changed);} 三、总结    到这里依赖属性的介绍就结束了。WPF中的依赖属性通过一个静态只读字段进行定义并且在静态构造函数中进行注册最后通过.NET传统属性进行包装使其使用与传统的.NET属性并无两样。在后面一篇文章将分享WPF中新的事件机制——路由事件。   本文所有源码下载DependencyPropertyDemo.zip   http://www.cnblogs.com/zhili/p/WPFLayout.html 转载于:https://www.cnblogs.com/sjqq/p/8350365.html
http://www.sadfv.cn/news/318122/

相关文章:

  • 做购物网站能不能赚钱网站设计评价标准
  • 网站制作公司下wordpress 禁止下载
  • 亳州公司做网站个人做淘宝客网站好做吗
  • 一键生成论文的网站海门网站建设
  • 网站备案查询不到说明啥企业网站营销的优缺点及案例
  • 邵阳网站建设wordpress iis7 伪静态
  • 苏州网站的优化网络营销推广实战宝典
  • 苏州创建网站高级wordpress搜索
  • 合肥网站建设黄页广州做家教的网站
  • 一对一视频网站建设办公空间设计思路
  • 青岛黄岛区网站开发个人博客登录入口
  • 网站设计培训费用是多少wordpress安装失败
  • 自己做网站难东莞理工学院教务处
  • 个人网站备案填写要求天河区建设网站
  • cms类型网站开发米拓建设网站
  • 长沙php的网站建设公司wordpress评论分页不显示不出来
  • 爱网站在线观看视频网络系统管理学什么
  • 广州网站设计提供商wordpress 模板检测
  • logo制作免费版网站关键词优化培训
  • 东海做网站公司品牌推广网站策划设计
  • 洛阳洛龙区网站建设河北省建设厅网站老版
  • 网站ns记录网页制作代码作业
  • 吴江市中云建设监理有限公司网站谷歌优化公司
  • 有没有网站教做美食的网站首页页脚设计
  • 广告设计就业方向口腔医院网站做优化
  • 全国招聘网站排名侵入别人的网站怎么做
  • 盘锦威旺做网站建设公司dw网站模板免费下载
  • 菏泽网站建设服务婚介 东莞网站建设
  • 网站建设费用是什么科目网站建设大
  • 12306网站建设网页设计培训班学费多少钱