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

MFC方式

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

Figure 1 MFC对话框 UI设计

IDD_MAINWIDNOW DIALOGEX , , ,
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "SendMessage"
MENU IDC_SENDMESSAGE
CLASS "SendMessage"
FONT , "MS Shell Dlg", , , 0x1
BEGIN
CONTROL ,IDC_CAPTURE,"Static",SS_BITMAP,,,,
GROUPBOX "Message",IDC_STATIC,,,,
COMBOBOX IDC_WINDOWSMESSAGE,,,,,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_LPARAM,,,,,ES_AUTOHSCROLL
EDITTEXT IDC_WPARAM,,,,,ES_AUTOHSCROLL
LTEXT "Results from window:",IDC_STATIC,,,,
EDITTEXT IDC_RESULTS,,,,,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
PUSHBUTTON "Send message",IDC_SENDMESSAGE,,,,
GROUPBOX "Window",IDC_STATIC,,,,
CONTROL "Message:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,,,,,WS_EX_RIGHT
CONTROL "wParam:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,,,,,WS_EX_RIGHT
CONTROL "lParam:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,,,,,WS_EX_RIGHT
CONTROL "Handle:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,,,,,WS_EX_RIGHT
EDITTEXT IDC_WINDOW_HANDLE,,,,,ES_AUTOHSCROLL
CONTROL "Window name:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,,,,,WS_EX_RIGHT
EDITTEXT IDC_WINDOW_NAME,,,,,ES_AUTOHSCROLL
EDITTEXT IDC_WINDOW_CLASS,,,,,ES_AUTOHSCROLL
CONTROL "Window class:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,,,,,WS_EX_RIGHT
PUSHBUTTON "Highlight Window",IDC_HIGHLIGHT_WINDOW,,,,
END

Figure 2 MFC对话框 UI代码

WPF方式

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

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

<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Hi There!" Height="" Width="">
<DockPanel>
<Button DockPanel.Dock=" Top" Background=" pink" > (Top)</Button>
<Button DockPanel.Dock=" Left" Background=" Orange" > (Left)</Button>
<Button DockPanel.Dock=" Right" Background=" Yellow" > (Right)</Button>
<Button DockPanel.Dock=" Bottom" Background=" Lime" > (Bottom)</Button>
<Button Background=" Aqua" ></Button>
</DockPanel>
</Window>

  Figure 3 简单WPF布局方式

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

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

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

<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Hi There!"
>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="File"/>
<MenuItem Header="Edit"/>
<MenuItem Header="View"/>
<MenuItem Header="Project"/>
<MenuItem Header="Build"/>
<MenuItem Header="Data"/>
<MenuItem Header="Tools"/>
<MenuItem Header="Window"/>
<MenuItem Header="Community"/>
<MenuItem Header="Help"/>
</Menu> <StackPanel Name="buttonBar" Orientation="Horizontal" DockPanel.Dock="Right">
<StackPanel.LayoutTransform>
<RotateTransform Angle="90"/>
</StackPanel.LayoutTransform>
<Button Name="pane1Button" MouseEnter="pane1Button_MouseEnter">
Toolbox
</Button>
<Button Name="pane2Button" MouseEnter="pane2Button_MouseEnter">
Solution Explorer
</Button>
</StackPanel> <Grid Name="parentGrid" Grid.IsSharedSizeScope="True"> <Grid Name="layer0" MouseEnter="layer0_MouseEnter">
<!-- Define four rows: -->
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions> <!-- Define two columns: -->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions> <Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Background="Blue" Foreground="White"
HorizontalContentAlignment="Center">
<Label.LayoutTransform>
<ScaleTransform ScaleX="2" ScaleY="2" />
</Label.LayoutTransform>
SolidMango
</Label>
<GroupBox Grid.Row="1" Grid.Column="0" Background="White"
Header="Recent Projects">...</GroupBox>
<GroupBox Grid.Row="2" Grid.Column="0" Background="White"
Header="Getting Started">...</GroupBox>
<GroupBox Grid.Row="3" Grid.Column="0" Background="White" Header="Headlines">...</GroupBox>
<GroupBox Grid.Row="1" Grid.Column="1" Grid.RowSpan="3" Background="White" Header="Online Articles">
<ListBox>
<ListBoxItem>Item #1</ListBoxItem>
<ListBoxItem>Item #2</ListBoxItem>
<ListBoxItem>Item #3</ListBoxItem>
<ListBoxItem>Item #4</ListBoxItem>
</ListBox>
</GroupBox>
</Grid> <Grid Name="layer1" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition SharedSizeGroup="column1" Width="auto"/>
</Grid.ColumnDefinitions> <Grid Grid.Column="1" MouseEnter="pane1_MouseEnter"
Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}" >
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions> <DockPanel Grid.Row="0">
<Button Width="26" Name="pane1Pin" DockPanel.Dock="Right" Click="pane1Pin_Click" Background="White">
<Image Name="pane1PinImage" Source="pinHorizontal.gif"/>
</Button>
<TextBlock Padding="8" TextTrimming="CharacterEllipsis" Foreground="{DynamicResource {x:Static SystemColors.ActiveCaptionTextBrushKey}}" DockPanel.Dock="Left">Toolbox</TextBlock>
</DockPanel>
<ListBox Padding="10" Grid.Row="1">
<ListBoxItem>Button</ListBoxItem>
<ListBoxItem>CheckBox</ListBoxItem>
<ListBoxItem>ComboBox</ListBoxItem>
<ListBoxItem>Label</ListBoxItem>
<ListBoxItem>ListBox</ListBoxItem>
</ListBox>
</Grid> <GridSplitter Width="5" Grid.Column="1" HorizontalAlignment="Left"/>
</Grid> <Grid Name="layer2" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition SharedSizeGroup="column2" Width="auto"/>
</Grid.ColumnDefinitions> <Grid Grid.Column="1" MouseEnter="pane2_MouseEnter" Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0">
<Button Width="26" Name="pane2Pin" DockPanel.Dock="Right" Click="pane2Pin_Click" Background="White">
<Image Name="pane2PinImage" Source="pinHorizontal.gif"/>
</Button>
<TextBlock Padding="8" TextTrimming="CharacterEllipsis" Foreground="{DynamicResource {x:Static SystemColors.ActiveCaptionTextBrushKey}}" DockPanel.Dock="Left">Solution Explorer</TextBlock>
</DockPanel>
<ToolBar Grid.Row="1">
<Button>
<Image Source="iconVSproperties.bmp"/>
</Button>
<Button>
<Image Source="iconVSshowall.bmp"/>
</Button>
<Button>
<Image Source="iconVSrefresh.bmp"/>
</Button>
</ToolBar>
<TreeView Grid.Row="2">
<TreeViewItem Header="My Solution">
<TreeViewItem Header="Project #1"/>
<TreeViewItem Header="Project #2"/>
<TreeViewItem Header="Project #3"/>
</TreeViewItem>
</TreeView>
</Grid> <GridSplitter Width="5" Grid.Column="1" HorizontalAlignment="Left"/>
</Grid>
</Grid>
</DockPanel>
</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. Ubuntu Tftpd服务配置

    ---恢复内容开始--- 服务器端(ip:192.168.1.100) #安装tftpd-hpa sudo apt-get install tftpd-hpa 修改配置文件 sudo vim /etc ...

  2. Replication的犄角旮旯(六)-- 一个DDL引发的血案(上)(如何近似估算DDL操作进度)

    <Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...

  3. .NET Core 1.0-最简单的Hello world控制台程序

    使用任意的文本编辑软件,新建两个文件 1.Program.cs using System; using System.Collections.Generic; using System.Linq; u ...

  4. AlwaysOn 同步时间的测试

    背景 <SQL Server 2012实施与管理实战指南>中指AlwaysON同步过程如下: 任何一个SQL Server里都有个叫Log Writer的线程,当任何一个SQL用户提交一个 ...

  5. Java多线程11:ReentrantLock的使用和Condition

    ReentrantLock ReentrantLock,一个可重入的互斥锁,它具有与使用synchronized方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大. Reentran ...

  6. 学习设计模式第三 - 基础使用UML表示关系

    面向对象的思想中存在如下几种关系,一般为了方便交流都使用UML的类图来展现类之间的关系.所以了解类图中符号的含义对看懂类图,尤其是用类图展示的设计模式很有帮助.下面依次介绍这几种关系 类继承关系 继承 ...

  7. Java提高篇(二六)-----hashCode

          在前面三篇博文中LZ讲解了(HashMap.HashSet.HashTable),在其中LZ不断地讲解他们的put和get方法,在这两个方法中计算key的hashCode应该是最重要也是最 ...

  8. 一天一小段js代码(no.1)

    10000个数字中缺少三个数,编程找出缺少的三个数字. 算法实现: /*生成10000个数中随机抽掉三个数后的数组*/ function supplyRandomArray(){ /*生成含有1000 ...

  9. 关于Windows高DPI的一些简单总结

    我们知道,关于高DPI的支持, Windows XP时代就开始有了, 那时关于高DPI的支持比较简单, 但是从Vista/Win7 到现在Win8 /Win8.1, Windows关于高DPI的支持已 ...

  10. [ZigBee] 3、ZigBee基础实验——GPIO输出控制实验-控制Led亮灭

    1.CC2530的IO口概述 CC2530芯片有21 个数字输入/输出引脚,可以配置为通用数字I/O 或外设I/O 信号,配置为连接到ADC.定时器或USART外设.这些I/O 口的用途可以通过一系列 ...