1.WPF 与Winform比较

1.1、WPF所有的操作都不依赖于GDI和GDI+,而是间接依赖于强大的Direct3D,这就意味着通过WPF可以做出以前WinFrom无法想象的视觉效果,包括3D效果的应用程序。

1.2、WPF实现彻底把程序架构,业务逻辑和用户界面(UI)彻底分开,WPF引擎把XAML描述的UI元素解释为相应的.NET对象,从而在应用程序创建相应的控件,UI人员和程序人员均可对此控件进行编辑加载,从而实现用户界面和程序架构的彻底分离,而Winform这一点是做不到的。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

优点:

1、wpf这个ui框架是很前沿的,包含了很多界面开发的特性,非常灵活,因为个人做界面开发比较多,包括web,iOS,android都接触过,wpf是我认为目前设计的最好的ui界面库
2、好的界面库有好的ide支持,vs的好用大家都懂得
3、一个功能多种实现方案,虽说灵活但实际对开发人员的要求更高,需要有更好的设计能力,追求优雅设计,MVVM模式讲究让界面代码尽量xaml化
4、强大的.net类库支持,ms平台的特性一向是入门简单,精通难,而且方案更新快,开发人员都比较依赖微软更新,开源力量还不够
5、基于DirectX渲染,渲染效率好,确实有很多优点
缺点:

1、内存占用高,基于.net的反射机制和wpf的内部机制,你想把控内存真心是难,只能一定程度控制,c++就不一样,内存是可控的
2、功能太多导致学习成本非常高,传统开发理念需要转换MVVM,但由于控件支持不完善,会出现不伦不类的情况
3、平台推广不利,这个才是最大原因,可以说是本人在.net多年学了很多,写代码是需要思考才能积累经验的,这种模式不适合互联网的快递跌代节奏,市场从业的机会太少,导致发展缓慢
4、功能不够完善,ms的客户端技术方案太多了,wpf只是其中一种,本来wp是一个机会,奈何wp又推不起来,个人感觉wp开发功能较wpf缩水厉害,后面又为silverlight加了很多轻量技术方案然后引入wpf,搞得不伦不类,已经把平台分为wpf,sl,wp,win 8 morden ui
5、平台真心混乱 自从 win8出来以后,我看到了win 8 morden ui,看了下sdk,又是一套api,感觉又是一个坑,果断决定放弃了,因为平台没有市场,去学习毫无意义,太多时间耗费在.net平台上了,感觉微软的策略真心是有问题,也得出一个结论,微软是一个比较喜欢玩技术的公司,跟着玩你会发现真的被玩了,现在看ios开发,反而感觉设计的好简单暴力,有时候给太多技术方案给开发人员不是一个好事情

最后总结
1、wpf技术是个好东西,是界面开发技术的精华,值得学习
2、wpf不是一切,是界面开发的一种方案,PC客户端开发坑很多,精通的话门槛很好,广会.net是不够的,底层得学
3、平台推广不给力是关键

作者:匿名用户
链接:https://www.zhihu.com/question/26862663/answer/76386239
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2.WPF 中XAML界面设计

一、基本语法

同XML类似,XAML中最基本的语法元素就是标签、属性、内容。

2.1、标签

标签是通常是以<>开始,以</>结束的,一个标签的声明通常表示一个对象。如<Window></Window>、<Grid></Grid>分别定义了一个窗体对象及一个Grid对象,标签定义有两种常用写法:

非自闭合签:<Window></Window>、<Grid></Grid>

自闭合标签:< Window />、 <Grid/>这种自闭合标签用于无内容情况下,可以让代码看上去更简洁,当然,正常情况下Window及Grid都是有内容的。

2.2、属性

属性通常以键值对形式出现,如<Window><Window/>标签中的Title="MainWindow" Height="350" Width="525",等号左边表示Window标签的属性,等号右边表示该属性的值。

2.3、内容

一组标签对之间夹杂的文本或其他标签都称为这个标签之间的内容。此处Window标签的内容就是一个<Grid><Grid/>标签

二、命名空间

细心的朋友肯定会问<Window>标签里的

 x:Class="WpfExam.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

这些奇奇怪怪的类似网站地址的是什么东东,难不成也是属性?没错,它们的确算是Window的属性,但他们又有自己独特的含义,基本上我们在WPF中新建任何窗体、用户控件,这三个属性都会出现。我们分别介绍这三个属性的是什么意思。

x:Class="WpfExam.MainWindow":这里指定了我们XAML窗体界面对应的C#类,是WpfExam命名空间下的MainWindow这个分部类。

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation":表示引用wpf界面表现相关的命名空间,类似于我们C#类中的using。

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml":表示引用xaml相关的命名空间。

这个xmlns:x中的x只是一个默认的标识符,如果我们将他改成y的话,编译我们的程序,将会报错找不到属性Class,此时我们就需要将x:Class="WpfExam.MainWindow"修改为y:Class="WpfExam.MainWindow"。

同样,如果我们将xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"也增加一个标示符号的话,假如我们改成xmlns:a="http://schemas.microsoft.com/winfx/2006/xaml/presentation",那么将会提醒你找不到类型

Window、Grid,你需要标签<Window>、<Grid>替换为<a:Window>、<a:Grid>

3.WPF控件基础

3.1 WPF控件简介

通过上一篇XAML语言的介绍,我们知道,XAML是一个树形结构,同样,WPF控件作为构成整个XAML树的一部分,也是一个树形结构。我们看一个简单的例子。

<Button.Content>
<DockPanel>
<Image Source="F:\01.Code\01.MyCode\WpfApplication1\WpfApplication1\Resources\荷.jpg" Width="30"/>
<TextBlock Text="红色" Foreground="Red" VerticalAlignment="Center"></TextBlock>
<TextBlock Text="绿色" Foreground="Green" VerticalAlignment="Center"/>
<TextBlock Text="蓝色" Foreground="Blue" VerticalAlignment="Center"/>
</DockPanel>
</Button.Content>

界面展现效果如图:

没有接触过WPF的朋友可能会惊讶,一个button里怎么会有那么多内容?我们可以通过VS的对象浏览器查看Button类的继承关系为:

Button->ButtonBase->ContentControl->Control->FrameworkElement。

FrameworkElement是所有WPF界面元素的展现基类(FrameworkElement向上继承自UIElement->Object),Button继承ContentControl,使得Button具备了一个容器控件应有的特性,即允许Button拥有一个Content,而这个Content可以为另一个容

器或控件,至于里面具体是什么,完全取决于你想要什么。这也正是WPF的魅力所在,任何控件都是一个树形结构,且树形结构的每一级都可以自由定制,理论上我们可以自定义任何一个层级的样式,来实现任何我们想要的界面展现效果。

3.2 WPF控件分类

上面我们讲到了Button继承自ContentControl,应该说是属于一个内容控件,下面我们系统的对WPF控件进行一下分类,按照我自己的理解,我们有两种分类方法。

一、按照控件的继承特性分类

我们先看一下整个WPF界面元素类之间的继承关系:

  • Panel:布局控件,包括Canvas、DockPanel、StackPanel等,可以容纳多个基本控件(Control)或者嵌套其他布局控件。用于整体界面的布局,Panel下的控件我们会在下一篇讲解。
  • Control:基本控件
  • ContentControl:内容控件,其内容只能是一个基本控件或布局控件,通常使用一个布局控件作为其Content,然后在布局空间里使用多个基本空间,从而实现复杂的界面效果,其下基本控件有Label、Button、Tooltip。
  • HeaderContentControl:带标题的内容控件,继承自ContentControl,在ContentControl的基础上,增加了一个Header属性。其下基本控件有TabItem、GroupBox等
  • ItemsControl:多条目控件,其下基本控件有ListBox、Menu等
  • HeaderItemsControl:继承自ItemsControl,增加了Header属性,其下控件有MenuItem、TreeViewItem、ToolBar等
  • TextBox:基本文本输入控件。
  • TextBlock、Image:直接继承自FrameworkElemet基类,属于最普通的基本控件。

二、按照控件的感官特性分类

这里的感官特性我定义的是,站在一个普通用户的角度上,能看到、感知到的东西。这里讲WPF控件分为两类:

1、 基本控件:用户可以看到并与之交互的控件,如按钮、输入框等,主要涵盖上述的Control、TextBlock、Image部分

2、 布局控件:用户察觉不到的,却对这个系统界面布局有着决定性作用的容器类控件,主要涵盖上述Panel及其子类部分

文章在以后的描述中将以这种分类方法进行阐述。

3.3 WPF控件属性

通过上面的介绍,我们知道所有的控件(基本控件、容器控件)都继承自FrameworkElement这个基类,这个基类里定义了WPF控件用到的大部分属性,我们这里先对这些WPF控件都具有的属性进行介绍(常用的标红),后续分别介绍常用基本控件时再对独有的属性进行介绍。

  • ActualHeight:获取此元素的呈现高度。
  • ActualWidth:获取次元素的呈现宽度。
  • BindingGroup:获取或设置用于该元素的 System.Windows.Data.BindingGroup
  • ContextMenu:获取或设置该元素的上下文菜单,通常是邮件菜单。
  • Cursor:获取或设置当鼠标指针悬停在此元素上时显示的光标
  • DataContext:获取或设置元素参与数据绑定时的数据上下文。
  • DefaultStyleKey:在使用或定义主题样式时,获取或设置用于引用此控件的样式的键。
  • FlowDirection:获取或设置文本和其他UI元素在控制它们布局的任何父元素中的流动方向。是一个枚举值。默认值为 System.Windows.FlowDirection.LeftToRight
  • FocusVisualStyle:获取或设置一个属性,该属性支持自定义将在此元素捕获键盘焦点时应用于此元素的外观、效果或其他样式特征
  • ForceCursor:获取或设置一个值,该值指示此元素是否应该强制UI按照Cursor属性所声明的方式呈现光标。
  • Height:获取或设置元素的建议高度。
  • HorizontalAlignment:获取或设置在父元素(如面板或项控件)中构成此元素时应用于此元素的水平对齐特征。
  • InputScope:获取或设置此元素使用的输入上下文
  • IsInitialized:获取一个值,该值指示此元素是否已初始化。
  • IsLoaded:获取一个值,该值指示是否已加载此元素以供呈现。
  • Language:获取或设置适用于某个元素的本地化/全球化语言信息
  • LayoutTransform:获取或设置在执行布局时应该应用于此元素的图形转换方式。
  • LogicalChildren:获取此元素的逻辑子元素的一个枚举器。
  • Margin:获取或设置元素的外边距。认值是所有属性都等于 0(零)的 System.Windows.Thickness。
  • MaxHeight:获取或设置元素的最大高度约束。
  • MaxWidth:获取或设置元素的最大宽度约束。
  • MinHeight:获取或设置元素的最小高度约束。
  • MinWidth:获取或设置元素的最小宽度约束。
  • Name:获取或设置元素的标识名称。该名称提供一个引用,以便当 XAML 处理器在处理过程中构造标记元素之后,后台代码可以对该元素进行引用。
  • OverridesDefaultStyle:获取或设置一个值,该值指示此元素是否合并了主题样式中的样式属性。
  • Parent:获取此元素的逻辑父级元素。
  • Resources:获取或设置本地定义的资源字典。
  • Style: 获取或设置此元素在呈现时使用的样式。
  • Tag: 获取或设置一个可用于存储有关此元素的自定义信息的任意对象值。
  • TemplatedParent: 获取一个对此元素的模板父级的引用。如果此元素不是通过模板创建而成,则此属性并不相关
  • ToolTip: 获取或设置在UI中为此元素显示的工具提示对象。
  • Triggers: 获取直接在此元素上建立或在子元素中建立的触发器的集合。
  • VerticalAlignment:获取或设置在父元素(如面板或项控件)中组合此元素时应用于此元素的垂直对齐特征。
  • VisualChildrenCount: 获取此元素内的可视化子元素的数目。
  • Width: 获取或设置元素的宽度。

       其中读写属性(带有获取或设置描述的属性)可以在XAML中使用,只读属性(只有获取描述的属性)只能在后台代码中使用。

4.WPF 中底层框架MVVM设计

View 和ViewModel 使用的是双向的数据属性

View 想把操作传到ViewModel ,它使用的是单向的命令属性

数据传输的数据属性

NotificationObject是ViewModel的基类

如果ViewModel属性借助Binding关联到界面上某个控件上,当这个值变化时候, Binding监听PropertyChanged这个事件有没有发生,一旦这个事件发生它将变化后的值送到界面上去。

Class NotificationObject:INotifyPropertyChanged

{

Public event PropertyChangedEventHandler PropertyChanged;

Public void RaisePropertyChange(string propertyName

{

  if(this.PropertyChanged!=null){

    this.PropertyChanged.Invoke(this,new PropertyChangedEventArgs(propertyName)); //告诉Data Binding 哪个属性值发生变化

  }

}

}

操作传输的命令属性

Class DelegateCommand:ICommand{

  public bool CanExecute(object parameter){

  if(this.CanExecuteFunc == null){

  return true;

  }

  this.CanExecuteFunc(parameter);

  } //这个方法用来帮助命令的呼叫者判断这个命令能不能执行

  public event EventHandler CanExecuteChanged; //当这个命令能不能执行这个状态发生改变的时候,有机会通知一下命令的调用者,告诉它状态change了

  public void Execute(object parameter){

   if(this.ExecuteAction == null){

   return;

   }

   this.ExecuteAction(parameter)

  }//命令执行的时候,你想做什么事情

  public Action<object> ExecuteAction{get;set;}//接受object类型Action

  public Func<object,bool> CanExecuteFunc{get;set;}//接受object类型,返回bool类型Func

}

public DelegateCommand SaveCommand{get;set;}

private void Save(object parameter){

  SaveFileDialog dlg= new SaveFileDialog();

  dlg.ShowDialog();

}

public MainWinowViewModel(){

  this.SaveCommand = new DelegateCommand();

  this.SaveCommand.ExecuteAction = new Action<object>(this.Save);

}

5.WPF 中async await - 性能开销和其他陷阱

1.避免对(耗时)短的方法使用async/await,避免在小循环内使用await语句(可以将整个循环放到一个async方法内)

2.忽略结果:忘记await一个函数返回的任务,将会导致乱序执行。

3.避免混合使用阻塞和非阻塞代码,这可能会导致死锁,更加复杂的错误处理以及上下文线程意外阻塞。

 所以在下面文章中防止死锁采用最好的方法是方案2,因为在方法中添加await调用,达到Context实际上永远不会被Block,所有的await都是asynchronous waits

 参照文章:http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

WPF 初识的更多相关文章

  1. 学习WPF——初识依赖项属性

    入门 首先创建一个依赖项属性 然后绑定父容器的DataContext到这个依赖项的实例 接着绑定子元素的属性到依赖项属性(注意Button的Content属性) 程序最终的运行结果:   说明 首先是 ...

  2. WPF自学入门(七)WPF 初识Binding

    今天记录一下Binding的基础和具体的使用方法,说起这个Binding,在WPF中,Binding是很重要的特征,在传统的Windows软件来看,大多数都是UI驱动程序的模式,也可以说事件驱动程序, ...

  3. WPF学习之路初识

    WPF学习之路初识   WPF 介绍 .NET Framework 4 .NET Framework 3.5 .NET Framework 3.0 Windows Presentation Found ...

  4. WPF学习之路(一) 初识WPF

    参考<葵花宝典-WPF自学手册> VS2012 先创建第一个WPF小程序 1.创建WPF程序 2.查看Solution,WPF中xaml文件和cs文件经常成对出现 两个主要的类:APP(W ...

  5. 学习WPF——WPF布局——初识布局容器

    StackPanel堆叠布局 StackPanel是简单布局方式之一,可以很方便的进行纵向布局和横向布局 StackPanel默认是纵向布局的 <Window x:Class="Wpf ...

  6. 初识MFC,WinForm,WPF,Q't

    MFC和QT是C++中常见的GUI框架,而WinForm和WPF是C#中常用的框架,不过我们一般很少叫WinForm框架,可能直接叫图形控件类库更多点.反正只是个称呼罢了,爱咋叫就咋叫.另外WinFo ...

  7. 初识MFC,WinForm,WPF,Q&#39;t

    MFC和QT是C++中常见的GUI框架,而WinForm和WPF是C#中常用的框架,不过我们一般很少叫WinForm框架,可能直接叫图形控件类库更多点.反正只是个称呼罢了,爱咋叫就咋叫.另外WinFo ...

  8. WPF从入门到放弃系列第一章 初识WPF

    什么是WPF WPF(Windows Presentation Foundation)是微软推出的基于Windows Vista的用户界面框架,属于.NET Framework 3.0的一部分.它提供 ...

  9. c# 初识WPF

    WPF,全名是Windows Presentation Foundation,是微软在.net3.0 WinFX中提出的.WPF是对Direct3D的托管封装,它的图形表现依赖于显卡.当然,作为一种更 ...

随机推荐

  1. spring jpa方法关键字转成sql

    The following table describes the keywords supported for JPA and what a method containing that keywo ...

  2. windows下的Redis主从集群搭建

    Redis官方不提供Windows版本,目前Windows下的版本是有微软开源团队(Microsoft Open Tech group)维护. http://redis.cn/ redis中文网 wi ...

  3. 02-cookie简单使用

    @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletExcep ...

  4. mysql 5.7 enable binlog

    0. precondition a) install mysql 5.7, for  detail please refer my blog post. 1. login mysql and chec ...

  5. JDK最新版 Jmeter最新版

    http://www.oracle.com/technetwork/java/javase/downloads/jdk10-downloads-4416644.html http://jmeter.a ...

  6. spring事务学习笔记

    事务管理器 default使用数据库默认的隔离级别

  7. vue2.0插件--loading

    loading效果很常见,常见到我们任何一个项目中,都可以见到他的身影.今天就以loading作为切入口,唠叨一下vuejs的插件的写法. 看vuejs官方文档关于插件的说明,关于使用插件和写插件,V ...

  8. make apr-util 报错 all recurisive

    安装expat库: yum install expat-devel 再次make 即可.

  9. Docker笔记——Docker安装及制作镜像

    1 Docker安装本文中Docker运行环境为Ubuntu 14.04.1 LTS 3.13.0-32-generic x64参考:https://docs.docker.com/v1.11/eng ...

  10. C#通过COM组件调用IDL的pro程序

    如果在“COM_IDL_connectLib.COM_IDL_connect oComIDL = new COM_IDL_connectLib.COM_IDL_connect();”步骤提示“...8 ...