对比MFC资源文件谈谈WPF布局方式

MFC方式

对于传统的MFC基于UI的应用程序设计通常分两步走,首先是设计UI,使用的是RC文件,然后是代码文件,对RC文件进行操作,如下面Figure 1 的基于对话框的应用程序,其对应的代码如Figure 2所示,这就是MFC时代的所见即所得,如大家所见,每个控件的代码都和位置都是写死的坐标,这样会带来的问题是当你改变系统运行的的DPI或者软件需要支持本地化的时候,由于有的语言对于同样的意思需要比较长的文字表示,就会带来文字显示不下或者显示不完整的情况。解决问题的方式想必大家都遇见过,手动的去拖拽控件的大小,然后再在不同的语言的系统上进行测试,整个过程异常繁琐,而且错误百出。

Figure 1 MFC对话框 UI设计

  1. IDD_MAINWIDNOW DIALOGEX , , ,
  2. STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
  3. CAPTION "SendMessage"
  4. MENU IDC_SENDMESSAGE
  5. CLASS "SendMessage"
  6. FONT , "MS Shell Dlg", , , 0x1
  7. BEGIN
  8. CONTROL ,IDC_CAPTURE,"Static",SS_BITMAP,,,,
  9. GROUPBOX "Message",IDC_STATIC,,,,
  10. COMBOBOX IDC_WINDOWSMESSAGE,,,,,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
  11. EDITTEXT IDC_LPARAM,,,,,ES_AUTOHSCROLL
  12. EDITTEXT IDC_WPARAM,,,,,ES_AUTOHSCROLL
  13. LTEXT "Results from window:",IDC_STATIC,,,,
  14. EDITTEXT IDC_RESULTS,,,,,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
  15. PUSHBUTTON "Send message",IDC_SENDMESSAGE,,,,
  16. GROUPBOX "Window",IDC_STATIC,,,,
  17. CONTROL "Message:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,,,,,WS_EX_RIGHT
  18. CONTROL "wParam:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,,,,,WS_EX_RIGHT
  19. CONTROL "lParam:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,,,,,WS_EX_RIGHT
  20. CONTROL "Handle:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,,,,,WS_EX_RIGHT
  21. EDITTEXT IDC_WINDOW_HANDLE,,,,,ES_AUTOHSCROLL
  22. CONTROL "Window name:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,,,,,WS_EX_RIGHT
  23. EDITTEXT IDC_WINDOW_NAME,,,,,ES_AUTOHSCROLL
  24. EDITTEXT IDC_WINDOW_CLASS,,,,,ES_AUTOHSCROLL
  25. CONTROL "Window class:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,,,,,WS_EX_RIGHT
  26. PUSHBUTTON "Highlight Window",IDC_HIGHLIGHT_WINDOW,,,,
  27. END

Figure 2 MFC对话框 UI代码

WPF方式

微软当然知道传统MFC程序的问题,终极的解决方案就是WPF布局,WPF的主流的最简单的布局方式有一下5种。

-Canvas
-StackPanel
-WrapPanel
-DockPanel
-Grid
举例来说DockPanel,简单的几行代码,对5个button进行了布局,大家可以看到,整个布局过程没有一个坐标,这样带来的还出就是改变窗口大小或者DPI,国际化,都不需要任何额外的工作,生活如此美好。

  1. <Window x:Class="WpfApp.MainWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. Title="Hi There!" Height="" Width="">
  5. <DockPanel>
  6. <Button DockPanel.Dock=" Top" Background=" pink" > (Top)</Button>
  7. <Button DockPanel.Dock=" Left" Background=" Orange" > (Left)</Button>
  8. <Button DockPanel.Dock=" Right" Background=" Yellow" > (Right)</Button>
  9. <Button DockPanel.Dock=" Bottom" Background=" Lime" > (Bottom)</Button>
  10. <Button Background=" Aqua" ></Button>
  11. </DockPanel>
  12. </Window>

  Figure 3 简单WPF布局方式

Figure 4 简单WPF布局方式效果图

当然WPF的能力不止于此,应用WPF完全可以做出基于MFC没办法做出来,或者很难做出来的效果,而且极其简单明了,这就是框架的力量,下面我们来看一个稍微复杂点的例子,当然这样的例子在网上随处可见,不作为奇,但是已经可以说明一定的问题。我们先来看看效果图,然后是源代码。

Figure 5 一个稍微复杂的WPF布局方式效果图

  1. <Window x:Class="MainWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. Title="Hi There!"
  5. >
  6. <DockPanel>
  7. <Menu DockPanel.Dock="Top">
  8. <MenuItem Header="File"/>
  9. <MenuItem Header="Edit"/>
  10. <MenuItem Header="View"/>
  11. <MenuItem Header="Project"/>
  12. <MenuItem Header="Build"/>
  13. <MenuItem Header="Data"/>
  14. <MenuItem Header="Tools"/>
  15. <MenuItem Header="Window"/>
  16. <MenuItem Header="Community"/>
  17. <MenuItem Header="Help"/>
  18. </Menu>
  19.  
  20. <StackPanel Name="buttonBar" Orientation="Horizontal" DockPanel.Dock="Right">
  21. <StackPanel.LayoutTransform>
  22. <RotateTransform Angle="90"/>
  23. </StackPanel.LayoutTransform>
  24. <Button Name="pane1Button" MouseEnter="pane1Button_MouseEnter">
  25. Toolbox
  26. </Button>
  27. <Button Name="pane2Button" MouseEnter="pane2Button_MouseEnter">
  28. Solution Explorer
  29. </Button>
  30. </StackPanel>
  31.  
  32. <Grid Name="parentGrid" Grid.IsSharedSizeScope="True">
  33.  
  34. <Grid Name="layer0" MouseEnter="layer0_MouseEnter">
  35. <!-- Define four rows: -->
  36. <Grid.RowDefinitions>
  37. <RowDefinition Height="Auto"/>
  38. <RowDefinition/>
  39. <RowDefinition/>
  40. <RowDefinition/>
  41. </Grid.RowDefinitions>
  42.  
  43. <!-- Define two columns: -->
  44. <Grid.ColumnDefinitions>
  45. <ColumnDefinition Width="Auto"/>
  46. <ColumnDefinition/>
  47. </Grid.ColumnDefinitions>
  48.  
  49. <Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Background="Blue" Foreground="White"
  50. HorizontalContentAlignment="Center">
  51. <Label.LayoutTransform>
  52. <ScaleTransform ScaleX="2" ScaleY="2" />
  53. </Label.LayoutTransform>
  54. SolidMango
  55. </Label>
  56. <GroupBox Grid.Row="1" Grid.Column="0" Background="White"
  57. Header="Recent Projects">...</GroupBox>
  58. <GroupBox Grid.Row="2" Grid.Column="0" Background="White"
  59. Header="Getting Started">...</GroupBox>
  60. <GroupBox Grid.Row="3" Grid.Column="0" Background="White" Header="Headlines">...</GroupBox>
  61. <GroupBox Grid.Row="1" Grid.Column="1" Grid.RowSpan="3" Background="White" Header="Online Articles">
  62. <ListBox>
  63. <ListBoxItem>Item #1</ListBoxItem>
  64. <ListBoxItem>Item #2</ListBoxItem>
  65. <ListBoxItem>Item #3</ListBoxItem>
  66. <ListBoxItem>Item #4</ListBoxItem>
  67. </ListBox>
  68. </GroupBox>
  69. </Grid>
  70.  
  71. <Grid Name="layer1" Visibility="Collapsed">
  72. <Grid.ColumnDefinitions>
  73. <ColumnDefinition/>
  74. <ColumnDefinition SharedSizeGroup="column1" Width="auto"/>
  75. </Grid.ColumnDefinitions>
  76.  
  77. <Grid Grid.Column="1" MouseEnter="pane1_MouseEnter"
  78. Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}" >
  79. <Grid.RowDefinitions>
  80. <RowDefinition Height="auto"/>
  81. <RowDefinition/>
  82. </Grid.RowDefinitions>
  83.  
  84. <DockPanel Grid.Row="0">
  85. <Button Width="26" Name="pane1Pin" DockPanel.Dock="Right" Click="pane1Pin_Click" Background="White">
  86. <Image Name="pane1PinImage" Source="pinHorizontal.gif"/>
  87. </Button>
  88. <TextBlock Padding="8" TextTrimming="CharacterEllipsis" Foreground="{DynamicResource {x:Static SystemColors.ActiveCaptionTextBrushKey}}" DockPanel.Dock="Left">Toolbox</TextBlock>
  89. </DockPanel>
  90. <ListBox Padding="10" Grid.Row="1">
  91. <ListBoxItem>Button</ListBoxItem>
  92. <ListBoxItem>CheckBox</ListBoxItem>
  93. <ListBoxItem>ComboBox</ListBoxItem>
  94. <ListBoxItem>Label</ListBoxItem>
  95. <ListBoxItem>ListBox</ListBoxItem>
  96. </ListBox>
  97. </Grid>
  98.  
  99. <GridSplitter Width="5" Grid.Column="1" HorizontalAlignment="Left"/>
  100. </Grid>
  101.  
  102. <Grid Name="layer2" Visibility="Collapsed">
  103. <Grid.ColumnDefinitions>
  104. <ColumnDefinition/>
  105. <ColumnDefinition SharedSizeGroup="column2" Width="auto"/>
  106. </Grid.ColumnDefinitions>
  107.  
  108. <Grid Grid.Column="1" MouseEnter="pane2_MouseEnter" Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}">
  109. <Grid.RowDefinitions>
  110. <RowDefinition Height="auto"/>
  111. <RowDefinition Height="auto"/>
  112. <RowDefinition/>
  113. </Grid.RowDefinitions>
  114. <DockPanel Grid.Row="0">
  115. <Button Width="26" Name="pane2Pin" DockPanel.Dock="Right" Click="pane2Pin_Click" Background="White">
  116. <Image Name="pane2PinImage" Source="pinHorizontal.gif"/>
  117. </Button>
  118. <TextBlock Padding="8" TextTrimming="CharacterEllipsis" Foreground="{DynamicResource {x:Static SystemColors.ActiveCaptionTextBrushKey}}" DockPanel.Dock="Left">Solution Explorer</TextBlock>
  119. </DockPanel>
  120. <ToolBar Grid.Row="1">
  121. <Button>
  122. <Image Source="iconVSproperties.bmp"/>
  123. </Button>
  124. <Button>
  125. <Image Source="iconVSshowall.bmp"/>
  126. </Button>
  127. <Button>
  128. <Image Source="iconVSrefresh.bmp"/>
  129. </Button>
  130. </ToolBar>
  131. <TreeView Grid.Row="2">
  132. <TreeViewItem Header="My Solution">
  133. <TreeViewItem Header="Project #1"/>
  134. <TreeViewItem Header="Project #2"/>
  135. <TreeViewItem Header="Project #3"/>
  136. </TreeViewItem>
  137. </TreeView>
  138. </Grid>
  139.  
  140. <GridSplitter Width="5" Grid.Column="1" HorizontalAlignment="Left"/>
  141. </Grid>
  142. </Grid>
  143. </DockPanel>
  144. </Window>

  

  Figure 6 一个稍微复杂的WPF布局方式源代码

总结

对比两种UI设计方式,读者不难看出,WPF对于UI设计的优越性是MFC RC方式无可匹敌的,无论是从生产力还是界面的美观性上来讲,差一代的技术,差的还是很明显的,WPF的UI设计方式受HTML的启发,在里面能看到很多的HTML的影子,当年微软以一个轻量级的WPF--silverlight 剑指 HTML,虽然silverlight 已经一败涂地,但是WPF仍然是Windows UI 设计的首选。

对比MFC资源文件谈谈WPF布局方式的更多相关文章

  1. 【spring Boot】spring boot获取资源文件的三种方式【两种情况下】

    首先声明一点,springboot获取资源文件,需要看是 1>从spring boot默认的application.properties资源文件中获取 2>还是从自定义的资源文件中获取 带 ...

  2. JavaWeb读取资源文件的四种方式

    1. ServletContext 1. 调用getResourcesAsStream方法获取输入流, 相对于webroot, 不用加/2. 读取任何类型的文件3. *只能在web环境下使用 Inpu ...

  3. 对比MFC和Winform及WPF

    MFC 生成本机代码,自然是很快.可是,消息循环,减缓了界面显示速度.winform 封装了 win32 的api,多次进行P/invoke 操作 (大部分使用p/invoke操作封装),速度慢 .w ...

  4. springmvc获取资源文件的两种方式(超简单)

    1 比如我们在sc目录下新建一个db.properties文件内容如下 DriverClass=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306 ...

  5. Springboot 创建的maven获取resource资源下的文件的两种方式

    Springboot 创建的maven项目 打包后获取resource下的资源文件的两种方式: 资源目录: resources/config/wordFileXml/wordFileRecord.xm ...

  6. Android笔记布局资源文件

    在项目的res--layout目录下的文件叫布局资源文件,用于控制页面的布局显示 在Java代码中引用布局资源我们已经很熟悉了. setContentView(R.layout.activity_ma ...

  7. Android开发之基本控件和详解四种布局方式

    Android中的控件的使用方式和iOS中控件的使用方式基本相同,都是事件驱动.给控件添加事件也有接口回调和委托代理的方式.今天这篇博客就总结一下Android中常用的基本控件以及布局方式.说到布局方 ...

  8. Android-基本控件和详解四种布局方式

    转自:https://www.cnblogs.com/ludashi/p/4883915.html 一.常用基本控件 1.TextView 看到Android中的TextView, 我不禁的想到了iO ...

  9. MFC,QT与WinForm,WPF简介

    编程语言的组成编程语言做为一种语言自然和英语这些自然语言有类似的地方.学英语时我们知道要先记26个字母,然后单词及其发音,接下来就是词组,句子.反正简单的说就是记单词,熟悉词法,句法.接下来就是应用了 ...

随机推荐

  1. MySql Windws 下自动备份脚本

    这几天正在做一个  使用MySQL数据库的项目,目前项目已经完成了,当部署好项目之后,正在考虑如何自动备份MySql数据库的问题,我在网上找了一下资料终于解决了,特此记录一下. @echo off e ...

  2. 图解js中常用的判断浏览器窗体、用户屏幕可视区域大小位置的方法

    有时我们需要获得浏览器窗口或屏幕的大小.窗口下拉框下拉的距离等数据,对应这些需求,js中提供了不少解决方法,只是数量稍多容易混淆它们各自的意义,下面咱们用图例来解释下12个常见对象属性的作用. 其中有 ...

  3. gtest 1.7编译错误:std:tr1:tuple模板参数过多的解决方案

    在gtest/gtest.h文件中添加如下代码 #define _VARIADIC_MAX 10

  4. Gradle中的buildScript代码块

    在编写Gradle脚本的时候,在build.gradle文件中经常看到这样的代码: build.gradle 1 2 3 4 5 6 7 8 9 buildScript { repositories ...

  5. 使用CSS sprites减少HTTP请求

    sprites是鬼怪,小妖精,调皮鬼的意思,初听这个高端洋气的名字我被震慑住了,一步步掀开其面纱后发觉很简单的东西,作用却很大 神马是CSS 小妖精 CSS sprites是指把网页中很多小图片(很多 ...

  6. Redmined的历史记录显示 "Updated by {{author}} {{age}} ago"

    最近Redmine出了点问题,简单查了一下,是ruby的本地冲突包i18n导致的, 先到redmine中跑命令: gem list --local,  查出本地ruby安装的所有的包 这里可以看到i1 ...

  7. 404 Not Found !

    MyEclipse中tomcat服务器运行好好的, 却总是报错, 代码没啥问题啊!! 之前都是运行好好的, 难道是我广告不小心改了哪里引起的?于是对比,回退代码,但是结果还是一样的!! 一个简简单单的 ...

  8. Oracle日期时间函数大全

    ORACLE日期时间函数大全 TO_DATE格式(以时间:2007-11-02 13:45:25为例) Year: yy two digits 两位年 显示值:07 yyy three digits ...

  9. Java-小练习简单银行程序

    2练习1:创建一个简单的银行程序包   练习目标-Java 语言中面向对象的封装性及构造器的使用. 任务 在这个练习里,创建一个简单版本的(账户类)Account类.将这个源文件放入banking程序 ...

  10. PHP基础 创建

    注意:1.网页文件放在wamp中的www文件下: 2.www文件下不能出现中文: 网页浏览的方法: 1.没有建立站点:localhost/文件所在位置 2.建立站点: (1)站点-新建站点-打开对话框 ...