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

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

MFC方式

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

         Figure 1 MFC对话框 UI设计

IDD_MAINWIDNOW DIALOGEX 0, 0, 201, 250
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 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    CONTROL         137,IDC_CAPTURE,"Static",SS_BITMAP,162,68,21,17
    GROUPBOX        "Message",IDC_STATIC,6,94,188,131
    COMBOBOX        IDC_WINDOWSMESSAGE,72,106,118,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
    EDITTEXT        IDC_LPARAM,72,124,118,14,ES_AUTOHSCROLL
    EDITTEXT        IDC_WPARAM,72,142,118,14,ES_AUTOHSCROLL
    LTEXT           "Results from window:",IDC_STATIC,12,162,70,8
    EDITTEXT        IDC_RESULTS,12,174,178,45,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
    PUSHBUTTON      "Send message",IDC_SENDMESSAGE,107,229,87,14
    GROUPBOX        "Window",IDC_STATIC,6,7,186,83
    CONTROL         "Message:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,12,108,54,8,WS_EX_RIGHT
    CONTROL         "wParam:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,12,126,54,8,WS_EX_RIGHT
    CONTROL         "lParam:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,12,144,54,8,WS_EX_RIGHT
    CONTROL         "Handle:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,12,18,54,8,WS_EX_RIGHT
    EDITTEXT        IDC_WINDOW_HANDLE,72,16,118,14,ES_AUTOHSCROLL
    CONTROL         "Window name:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,12,34,54,8,WS_EX_RIGHT
    EDITTEXT        IDC_WINDOW_NAME,72,32,118,14,ES_AUTOHSCROLL
    EDITTEXT        IDC_WINDOW_CLASS,72,48,118,14,ES_AUTOHSCROLL
    CONTROL         "Window class:",IDC_STATIC,"Static",SS_SIMPLE | WS_GROUP,12,50,54,8,WS_EX_RIGHT
    PUSHBUTTON      "Highlight Window",IDC_HIGHLIGHT_WINDOW,12,72,96,14
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="350" Width="525">
<DockPanel>
<Button DockPanel.Dock=" Top" Background=" pink" >1 (Top)</Button>
<Button DockPanel.Dock=" Left" Background=" Orange" >2 (Left)</Button>
<Button DockPanel.Dock=" Right" Background=" Yellow" >3 (Right)</Button>
<Button DockPanel.Dock=" Bottom" Background=" Lime" >4 (Bottom)</Button>
<Button Background=" Aqua" >5</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 设计的首选。

原文地址:https://www.cnblogs.com/pugang/p/4333367.html