WPF“Half the Whitespace”设计原则

基础知识

WPF(Windows Presentation Foundation)是Microsoft推荐的经典Windows桌面应用程序演示技术。 WPF不应与UWP(通用Windows平台)混淆,尽管两者之间存在相似之处。

WPF鼓励数据驱动的应用程序,重点关注多媒体,动画和数据绑定。使用称为XAML(可扩展应用程序标记语言)的语言创建接口,XAML是XML的衍生物。 XAML帮助WPF程序员保持视觉设计和界面逻辑的分离。

与其前身Windows窗体不同,WPF使用盒子模型来布局界面的所有元素。每个元素都有一个高度,宽度和边距,并在屏幕上相对于它的父元素排列。

WPF代表Windows Presentation Foundation,也以其Codename Avalon而闻名。它是一个图形框架,是Microsofts .NET Framework的一部分。 WPF预安装在Windows Vista,7,8和10中,可以安装在Windows XP和Server 2003上。

 

版本

版本4.6.1 - 2015年12月

 

Hello World应用程序#

在Visual Studio中创建和运行新的WPF项目: 

单击文件→新建→项目

单击模板→Visual C#→Windows→WPF应用程序选择模板,然后按确定 : 

在解决方案资源管理器中打开MainWindow.xaml文件(如果没有看到解决方案资源管理器窗口,请单击查看→解决方案资源管理器打开它): 

在XAML部分(默认情况下在“ 设计”部分下面)添加此代码

<TextBlock>Hello world!</TextBlock>

Grid 标签内: 

代码应如下所示:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBlock>Hello world!</TextBlock>
    </Grid>
</Window>

F5或单击菜单Debug→Start Debugging运行应用程序。它应该看起来像:

“Half the Whitespace”设计原则 

在布置控件时,很容易在边距和填充中硬编码特定值,以使事物适合所需的布局。但是,通过对这些值进行硬编码,维护变得更加昂贵。如果布局发生变化,可能被认为是一种微不足道的方式,那么很多工作必须用于纠正这些值。

该设计原理通过以不同方式考虑布局来降低布局的维护成本。 

wpf 如何在实际代码中使用它

概括我们上面已经证明的内容:单个事物包含“半空白”的固定边距 ,并且它们所容纳的容器应该具有“半空白”的填充 。你可以在应用程序资源字典中应用这些样式,然后你甚至不需要在单个项目上提及它们。以下是你可以定义“HalfTheWhiteSpace”的方法:

<system:Double x:Key="DefaultMarginSize">2</system:Double>
<Thickness x:Key="HalfTheWhiteSpace" Left="{StaticResource DefaultMarginSize}" Top="{StaticResource DefaultMarginSize}" Right="{StaticResource DefaultMarginSize}" Bottom="{StaticResource DefaultMarginSize}"/>

然后我可以定义一个基本样式来基于我的其他控件样式:(这也可以包含你的默认FontFamily,FontSize等等)

<Style x:Key="BaseStyle" TargetType="{x:Type Control}">
    <Setter Property="Margin" Value="{StaticResource HalfTheWhiteSpace}"/>
</Style>

然后我可以为TextBox定义我的默认样式以使用此边距:

<Style TargetType="TextBox" BasedOn="{StaticResource BaseStyle}"/>

我可以为DatePickers,Labels等等做任何事情(可能在容器中保存的任何东西)。小心像这样的TextBlock样式......该控件在很多控件内部使用。我建议你创建自己的控件,它只是从TextBlock派生。你可以风格你的TextBlock使用默认的保证金;每当你明确地使用一个TextBlock在XAML,你应该用你的TextBlock。

你可以使用类似的方法将填充应用于常见容器(例如ScrollViewer,Border等)。

完成此操作后, 大多数控件都不需要边距和填充 - 你只需要在有意偏离此设计原则的位置指定值。 

演示问题和解决方案

例如,想象一个有3个部分的屏幕,如下所示: 

蓝框的边距可能为4,4,0,0。绿框的边距可能为4,4,4,0。紫色框边距为4,4,4,4。这是XAML :(我使用网格来实现布局;但无论您选择如何实现布局,此设计原则都适用):

<UserControl x:Class="WpfApplication1.UserControl1HardCoded"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="3*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="2*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <Border Grid.Column="0" Grid.Row="0" Margin="4,4,0,0" Background="DodgerBlue" BorderBrush="DarkBlue" BorderThickness="5"/>
    <Border Grid.Column="1" Grid.Row="0" Margin="4,4,4,0" Background="Green" BorderBrush="DarkGreen" BorderThickness="5"/>
    <Border Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Margin="4,4,4,4" Background="MediumPurple" BorderBrush="Purple" BorderThickness="5"/>
</Grid>
</UserControl>

现在想象一下,我们想要更改布局,将绿色框放在蓝色框的左侧。应该简单,不应该吗?除了当我们移动那个盒子时,我们现在需要修补边缘。要么我们可以将蓝框的边距改为0,4,4,0;或者我们可以将蓝色变为4,4,4,0,将绿色变为4,4,0,0。这是XAML:

<UserControl x:Class="WpfApplication1.UserControl1HardCoded"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="3*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="2*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <Border Grid.Column="0" Grid.Row="0" Margin="0,4,4,0" Background="DodgerBlue" BorderBrush="DarkBlue" BorderThickness="5"/>
    <Border Grid.Column="1" Grid.Row="0" Margin="4,4,4,0" Background="Green" BorderBrush="DarkGreen" BorderThickness="5"/>
    <Border Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Margin="4,4,4,4" Background="MediumPurple" BorderBrush="Purple" BorderThickness="5"/>
</Grid>
</UserControl>

现在让我们把紫色的盒子放在顶部。所以蓝色的利润率变为4,0,4,4;绿色变为4,0,0,4。

<UserControl x:Class="WpfApplication1.UserControl1HardCoded"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="3*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="2*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

        <Border Grid.Column="0" Grid.Row="0" Margin="4,0,4,4" Background="DodgerBlue" BorderBrush="DarkBlue" BorderThickness="5"/>
    <Border Grid.Column="1" Grid.Row="0" Margin="4,0,0,4" Background="Green" BorderBrush="DarkGreen" BorderThickness="5"/>
    <Border Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Margin="4,4,4,4" Background="MediumPurple" BorderBrush="Purple" BorderThickness="5"/>
</Grid>
</UserControl>

如果我们能够移动其他东西以便我们根本不需要调整这些值,那不是很好。这可以通过以不同的方式考虑空白来实现。想象一下将所有空白分配给一个控件或另一个控件,而不是将每个盒子的一半空白分配给每个盒子:(我的绘图不是很容易缩放 - 虚线应该在盒子边缘和它的邻居之间的中间位置) 。

所以蓝盒的边距为2,2,2,2;绿箱的边距为2,2,2,2;紫色方框的边距为2,2,2,2。并且容纳它们的容器具有2,2,2,2的填充物(不是边缘)。这是XAML:

<UserControl x:Class="WpfApplication1.UserControl1HardCoded"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             Padding="2,2,2,2">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="3*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="2*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

        <Border Grid.Column="0" Grid.Row="0" Margin="2,2,2,2" Background="DodgerBlue" BorderBrush="DarkBlue" BorderThickness="5"/>
        <Border Grid.Column="1" Grid.Row="0" Margin="2,2,2,2" Background="Green" BorderBrush="DarkGreen" BorderThickness="5"/>
        <Border Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Margin="2,2,2,2" Background="MediumPurple" BorderBrush="Purple" BorderThickness="5"/>
</Grid>
</UserControl>

现在让我们尝试移动盒子,就像以前一样......让我们把绿色框放在蓝色框的左边。 OK完成。并且无需更改任何填充或边距。这是XAML:

<UserControl x:Class="WpfApplication1.UserControl1HardCoded"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             Padding="2,2,2,2">
<Grid>
    <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="3*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="2*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

        <Border Grid.Column="0" Grid.Row="0" Margin="2,2,2,2" Background="DodgerBlue" BorderBrush="DarkBlue" BorderThickness="5"/>
        <Border Grid.Column="1" Grid.Row="0" Margin="2,2,2,2" Background="Green" BorderBrush="DarkGreen" BorderThickness="5"/>
        <Border Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Margin="2,2,2,2" Background="MediumPurple" BorderBrush="Purple" BorderThickness="5"/>
</Grid>
</UserContro>

 

现在让我们把紫色的盒子放在顶部。 OK完成。并且无需更改任何填充或边距。这是XAML:

<UserControl x:Class="WpfApplication1.UserControl1HardCoded"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             Padding="2,2,2,2">
<Grid>
    <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="3*"/>
        </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="2*"/>
    </Grid.RowDefinitions>

        <Border Grid.Column="1" Grid.Row="1" Margin="2,2,2,2" Background="DodgerBlue" BorderBrush="DarkBlue" BorderThickness="5"/>
        <Border Grid.Column="0" Grid.Row="1" Margin="2,2,2,2" Background="Green" BorderBrush="DarkGreen" BorderThickness="5"/>
        <Border Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Margin="2,2,2,2" Background="MediumPurple" BorderBrush="Purple" BorderThickness="5"/>
</Grid>
</UserControl>

posted @ 2020-01-02 11:15  N-COUNT  阅读(292)  评论(0编辑  收藏  举报