Good XAML Patterns

1:写xaml的时候写在multiply line里(使用Xaml Styler插件会自动转行)。

2:Naming Conventient

  • Resources以文件名.key的形式写:InputPageOilSwellResources.DesignNameColumnStyle,若已经在本层的话就不用写文件名了。
  • x:Name应该用'_master'的形式,同coding的private
  • 命名resources的时候either是style或者Template写成 DesignNameColumnStyle, DesignNameColumnTemplate,中间没有其他的连字符。
  • CommonResources的文件名命名
<!-- __________________________ ProjectName_Text_Styles_Library.xaml  _________________________________-->
<!-- __________________________ ProjectName_Icon_Library.xaml  _________________________________-->
<!-- __________________________ ProjectName_Control_Styles_Library.xaml  _________________________________-->
<!-- __________________________ ProjectName_UnitControl_Styles_Library.xaml  _________________________________-->
<!-- __________________________ ProjectName_ListControl_Styles_Library.xaml  _________________________________-->



<!-- ALL FONTS MUST BE EMBEDDED IN THE COMMON "FONTS" FOLDER, 

	AND A BASE FONT STYLE IS CREATED BELOW.  IDIVIDUAL STYLES FOR LABELS AND TITLES WILL BE

	CREATED USING THE "BasedOn" FUNCTION -->

3:选用正确的container:如果需要按钮和textbox并排之间有一个gap,就不要用3列的grid做,应该用stackpanel和空间自身的padding,magging。

4: DataTemplate后面最好有x:Type

<DataTemplate DataType={x:Type string}>



    <TextBlock Text={Binding}>

</DataTemplate>



//这里最好加上DataType属性,来指明binding的是什么类型,自己方便。

5: ControlTemplate一定要有TargetType,不然消费这个CT资源会有显示不出结果的问题

<ControlTemplate TargetType = {x:Type ...}>



    .....

</ControlTemplate>



//包括其上面的style也一定要有TargetType 
 
  


6:所有page都会用到的resources像Fonts都放在高层,如windows层或者App层。

建议放在APP层:Resources defined at the application level can be accessed by all other pages that are part of the application.

<Window>

    <Style>

        Fonts定义......

    </Style>

</Window>

 

7:区分ContentPresanter 和 ContentControls

ContentControl is the base class for every control that have"content" need to display (example: Button, Label).

ContentPresenter is the placeholder used inside DT or CT by ContentControl to display the content

注意:

ContentControl里有三个属性(Content,  Template, ContentTemplate)CT里包含ContentPresenter,用来吧外层的Content属性拿进CT,而ContentPresenter的格式就是ContentTemplate

               Object   CT      DT

ContentPresenter里只有两个属性(Content, ContentTemplate)没有Template属性,使用在任何Control的DT或者CT内部显示content。

                 Object      DT

//这个从contentpresenter的class定义就可以看出

Class ContentPresenter

{

    public Object Content{get; set;}

    public DataTemplate ContentTemplate{get; set;}      

}

如何使用ContentControl(比如Button)的ContentTemplate呢?

 

<Window

        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" mc:Ignorable="d" x:Class="WpfApplication4.MainWindow"

        Title="MainWindow" Height="350" Width="225">

    <Window.Resources>

        <DataTemplate x:Key="ButtonContentTemplate">

            <StackPanel Orientation="Horizontal">

                <Grid Height="8" Width="8">

                    <Path HorizontalAlignment="Stretch" 

                        Margin="0,0,1.8,1.8" 

                        VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FF000000" 

                        Data="M0.5,5.7 L0.5,0.5 L5.7,0.5"/>

                    <Path HorizontalAlignment="Stretch" 

                        Margin="2,3,0,0" 

                        VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FFFFFFFF" 

                        Data="M3.2,7.5 L7.5,7.5 L7.5,3.5"/>

                    <Path HorizontalAlignment="Stretch" 

                        Margin="1.2,1.4,0.7,0.7" 

                        VerticalAlignment="Stretch" Fill="#FFFFFFFF" Stretch="Fill" Stroke="#FF000000" 

                        Data="M2.5,2.5 L7.5,7.5"/>

                    <Path HorizontalAlignment="Stretch" 

                        Margin="1.7,2.0,1,1" 

                        VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FF000000" 

                        Data="M3,7.5 L7.5,7.5 L7.5,3.5"/>

                    <Path HorizontalAlignment="Stretch" 

                        Margin="1,1,1,1" 

                        VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FFFFFFFF" 

                        Data="M1.5,6.5 L1.5,1 L6.5,1.5"/>

                </Grid>

                <ContentPresenter Content="{Binding}"/>

            </StackPanel>

    </DataTemplate>

    

    <ControlTemplate TargetType="Button" x:Key="ButtonControlTemplate">

      <Grid>

        <Ellipse Fill="{TemplateBinding Background}"/>

        <ContentPresenter HorizontalAlignment="Center"

              VerticalAlignment="Center"/>

      </Grid>

    </ControlTemplate>

    </Window.Resources>



    <StackPanel>

    <Button Template="{StaticResource ButtonControlTemplate}" Content="1"/>

    <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="2"/>

    <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="3"/>

  </StackPanel>

</Window>

 

 

 

 

8: PFG2独门秘笈,自定义ContentProperty

Object类可以是任何(Text,Image)

 

      ContentControl        workwith       ControlTemplate

        Property     Type                 Must have type <ControlTemplate TargetType={x:Type Button}>

          Content     Object

    ContentTemplate     DataTemplate

        Template     ControlTemplate

 

 

      ContentPresenter       workwith          DataTemplate

         Property     Type               Better have type <DataTemplate DataType={x:Type sys:string}>

         Content     Object

   ContentTemplate     DataTemplate


ContentProperty的class定义

View Code
......

public static readonly DependencyProperty TextStyleProperty;

        [AttachedPropertyBrowsableForType(typeof(FrameworkElement))]

        public static Style GetTextStyle(DependencyObject d)

        {

            return (Style)d.GetValue(TextStyleProperty);

        }

        public static void SetTextStyle(DependencyObject d, Style value)

        {

            d.SetValue(TextStyleProperty, value);

        }

......



public static readonly DependencyProperty StyleProperty;

        [AttachedPropertyBrowsableForType(typeof(FrameworkElement))]

        public static Style GetStyle(DependencyObject d)

        {

            return (Style)d.GetValue(StyleProperty);

        }

        public static void SetStyle(DependencyObject d, Style value)

        {

            d.SetValue(StyleProperty, value);

        }



......

 

注册一个(x:Key="CaretedUnderlined2WrappingTextTemplate")的DataTemplate为某个控件的ContentTemplate属性赋值。

DataTemplate是给控件的ContentTemplatre属性服务的,该DataTemplate下的TextBlock分别被binding到其父的不同属性上(c:ContentProperties.Text 和 c:ContentProperties.Text2)。

View Code
 <DataTemplate x:Key="CaretedUnderlined2WrappingTextTemplate">

        <Grid>

            <Grid.ColumnDefinitions>

                <ColumnDefinition Width="10"/>

                <!-- Caret Margin -->

                <ColumnDefinition Width="*"/>

            </Grid.ColumnDefinitions>



            <Image Width="8" HorizontalAlignment="Left" Grid.Column="0" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5"

                       Source="{Binding Source={StaticResource Icon_ArrowCaretDown}, Converter={StaticResource CaretIconToBrushConverter}}">

                <Image.RenderTransform>

                    <TransformGroup>

                        <RotateTransform Angle="-90"/>

                    </TransformGroup>

                </Image.RenderTransform>

            </Image>

            <Rectangle Grid.Column="1" x:Name="BackgroundRect" Style="{TemplateBinding common:ContentProperties.Style}" />

            <Canvas Grid.Column="1" VerticalAlignment="Bottom">

                <Line X2="{Binding ElementName=BackgroundRect, Path=ActualWidth}" Style="{TemplateBinding common:ContentProperties.Style2}"/>

            </Canvas>

            <DockPanel VerticalAlignment="Center" Grid.Column="1" x:Name="DockPanel" >

                <TextBlock Text="{TemplateBinding common:ContentProperties.Text}" 

                           Style="{TemplateBinding common:ContentProperties.TextStyle}" 

                           DockPanel.Dock="Left" x:Name="text1"/>

                <TextBlock Text="{TemplateBinding common:ContentProperties.Text2}"

                           Style="{TemplateBinding common:ContentProperties.TextStyle2}" 

                           DockPanel.Dock="Right" TextAlignment="Right"/>

            </DockPanel>

        </Grid>

    </DataTemplate>

创建一个新的style,x:Key="DottedLine2TextBlockWrappingStyle"TargetType="{x:Type ContentControl}",对其间的contentproperties修改。

<Style x:Key="DottedLine2TextBlockWrappingStyle" TargetType="{x:Type ContentControl}">

        <Setter Property="ContentTemplate" Value="{StaticResource Underlined2TextTemplate}"/>

        <Setter Property="common:ContentProperties.Style" Value="{StaticResource UnderlineBlockBackgroundStyle}"/>

        <Setter Property="common:ContentProperties.Style2" Value="{StaticResource DottedLineStyle}"/>

        <Setter Property="common:ContentProperties.TextStyle" Value="{StaticResource SmallLightText}"/>

        <Setter Property="common:ContentProperties.TextStyle2" Value="{StaticResource SmallMedTextWrapping}"/>

    </Style>
 1 <DataTemplate x:Key="CaretedUnderlined2WrappingTextTemplate">

 2         <Grid>

 3             <Grid.ColumnDefinitions>

 4                 <ColumnDefinition Width="10"/>

 5                 <!-- Caret Margin -->

 6                 <ColumnDefinition Width="*"/>

 7             </Grid.ColumnDefinitions>

 8 

 9             <Image Width="8" HorizontalAlignment="Left" Grid.Column="0" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5"

10                        Source="{Binding Source={StaticResource Icon_ArrowCaretDown}, Converter={StaticResource CaretIconToBrushConverter}}">

11                 <Image.RenderTransform>

12                     <TransformGroup>

13                         <RotateTransform Angle="-90"/>

14                     </TransformGroup>

15                 </Image.RenderTransform>

16             </Image>

17             <Rectangle Grid.Column="1" x:Name="BackgroundRect" Style="{TemplateBinding common:ContentProperties.Style}" />

18             <Canvas Grid.Column="1" VerticalAlignment="Bottom">

19                 <Line X2="{Binding ElementName=BackgroundRect, Path=ActualWidth}" Style="{TemplateBinding common:ContentProperties.Style2}"/>

20             </Canvas>

21             <DockPanel VerticalAlignment="Center" Grid.Column="1" x:Name="DockPanel" >

22                 <TextBlock Text="{TemplateBinding common:ContentProperties.Text}" 

23                            Style="{TemplateBinding common:ContentProperties.TextStyle}" 

24                            DockPanel.Dock="Left" x:Name="text1"/>

25                 <TextBlock Text="{TemplateBinding common:ContentProperties.Text2}"

26                            Style="{TemplateBinding common:ContentProperties.TextStyle2}" 

27                            DockPanel.Dock="Right" TextAlignment="Right"/>

28             </DockPanel>

29         </Grid>

30     </DataTemplate>

注意<Setter Property="common:ContentProperties.Style" Value="{StaticResource UnderlineBlockBackgroundStyle}"/>的reources在某个地方有定义

 

下面注册一个style,用来加载到一个控件的ContentTemplate,并且BasedOn="{StaticResource DottedLine2TextBlockWrappingStyle}

<Style x:Key="CaretedDottedLine2TextBlockWrappingStyle" TargetType="{x:Type ContentControl}" BasedOn="{StaticResource DottedLine2TextBlockWrappingStyle}">

        <Setter Property="ContentTemplate" Value="{StaticResource CaretedUnderlined2WrappingTextTemplate}"/>

    </Style>

 

<Style x:Key="DottedLine2TextBlockWrappingStyle" TargetType="{x:Type ContentControl}">

        <Setter Property="ContentTemplate" Value="{StaticResource Underlined2TextTemplate}"/>

        <Setter Property="common:ContentProperties.Style" Value="{StaticResource UnderlineBlockBackgroundStyle}"/>

        <Setter Property="common:ContentProperties.Style2" Value="{StaticResource DottedLineStyle}"/>

        <Setter Property="common:ContentProperties.TextStyle" Value="{StaticResource SmallLightText}"/>

        <Setter Property="common:ContentProperties.TextStyle2" Value="{StaticResource SmallMedTextWrapping}"/>

    </Style>

在某一个地方可以使用这个ContentTemplate了

                <StackPanel Grid.Column="1" Grid.Row="4" VerticalAlignment="Top">

                    <ContentControl Style="{StaticResource CaretedDottedLine2TextBlockWrappingStyle}"

                                            c:ContentProperties.Text="Customer or customer's agent (please print):"

                                            c:ContentProperties.Text2="{Binding Data.CusOrCusAgentPrint}"/>

                    <ContentControl Style="{StaticResource CaretedDottedLine2TextBlockWrappingStyle}"

                                            c:ContentProperties.Text="Customer or customer's agent (signature):"

                                            c:ContentProperties.Text2="{Binding Data.CusOrCusAgentSignature}"/>



                </StackPanel>

 

8:Half Design Pattern: 如果control与control之间如果需要10margin的空间,我们可以给每个control左右各5的margin. 最外面的Container也给5的margin,这样所有的control之间和与最外面的界面边框之间都是10个margin

9: Extension Container Pattern:如果要Grid里要加入更多的control时我们又不希望重新分配grid的列或者行,我们可以把之前某一行/列包含在一个statckpanel里,以便所以增减项目。

10. Leaf Margin Pattern:给margin的时候放在做末尾。

 

 

你可能感兴趣的:(Pattern)