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的时候放在做末尾。

 

 

posted @ 2013-03-07 06:54  若愚Shawn  阅读(268)  评论(0编辑  收藏  举报