乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      WPF 詳解模板

       xyjackxjw 2013-05-16

      WPF 詳解模板

      在WPF中有三大模板ControlTemplate,ItemsPanelTemplate,DataTemplate.其中ControlTemplate和ItemsPanelTemplate是控件模板,DataTemplate是數(shù)據(jù)模板,他們都派生自FrameworkTemplate抽象類。

      1、ControlTemplate

      ControlTemplate:控件模板主要有兩個重要屬性:VisualTree內(nèi)容屬性和Triggers觸發(fā)器。所謂VisualTree(視覺樹),就是呈現(xiàn)我們所畫的控件。Triggers可以對我們的視覺樹上的元素進行一些變化。一般用于單內(nèi)容控件。

      畫一個按鈕模板來舉例說明:

      <Style TargetType="Button">
                  <Setter Property="Template">
                      <Setter.Value>
                          <ControlTemplate TargetType="Button">
                              <Grid>
                                  <Ellipse Width="100" Height="100">
                                      <Ellipse.Fill>
                                          <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                              <GradientStop Offset="0" Color="blue"/>
                                              <GradientStop Offset="1" Color="LightBlue"/>
                                          </LinearGradientBrush>
                                      </Ellipse.Fill>
                                  </Ellipse>
                                  <Ellipse Width="80" Height="80">
                                      <Ellipse.Fill>
                                          <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                              <GradientStop Offset="0" Color="White"/>
                                              <GradientStop Offset="1" Color="Transparent"/>
                                          </LinearGradientBrush>
                                      </Ellipse.Fill>
                                  </Ellipse>
                              </Grid>
                          </ControlTemplate>
                      </Setter.Value>
                  </Setter>
              </Style>

      <Button Content="Hello WPF"/>

      結果:image

      ControlTemplate之子 ContentControl和ContentPresenter

      我們在ControlTemplate中畫了兩個橢圓,應用于所有的Button按鈕,但我們Button中有Content屬性(內(nèi)容為Hello WPF),卻沒有顯示出來。因為這里用ControlTemplate重寫了Button的樣式,所以我們也要在ControlTemplate中增加ContentControl。通過ContentControl中的Content來綁定父容器的Content屬性。

      <Style TargetType="Button">
                  <Setter Property="Template">
                      <Setter.Value>
                          <ControlTemplate TargetType="Button">
                              <Grid>
                                  <Ellipse Width="100" Height="100">
                                      <Ellipse.Fill>
                                          <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                              <GradientStop Offset="0" Color="blue"/>
                                              <GradientStop Offset="1" Color="LightBlue"/>
                                          </LinearGradientBrush>
                                      </Ellipse.Fill>
                                  </Ellipse>
                                  <Ellipse Width="80" Height="80">
                                      <Ellipse.Fill>
                                          <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                              <GradientStop Offset="0" Color="White"/>
                                              <GradientStop Offset="1" Color="Transparent"/>
                                          </LinearGradientBrush>
                                      </Ellipse.Fill>
                                  </Ellipse>
                                  <ContentControl VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}"/>
                              </Grid>
                          </ControlTemplate>
                      </Setter.Value>
                  </Setter>
              </Style>
      

      這下內(nèi)容出來了image

      我們來看一下,ContentControl繼承于Control的,用MSDN的話是:表示包含單項內(nèi)容的控件、ContentControl 可以包含任何類型的公共語言運行庫對象。如下ContentControl類圖。

      image

      為了提高性能,我們可以用一個ControlPresenter來代替ContentControl,效果還是一樣,那他們有什么區(qū)別呢?

      來看下ControlPresenter這個類,它繼承于FreameworkElement,如下圖:

      image

      ControlPresenter 通常叫做內(nèi)容占位符。所以我們可以看到

      <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>來代替<ContentControl VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}"/> 。這里少了Content綁定父容器,因為ControlPresenter有個隱式的Content="{TemplateBinding Content}",也就是你可以寫也可以不寫它。

      從他們的基類可以看出,ContentControl比ContentPresenter大多了。其實ControlPresenter是一個原始的構建塊,而ContentControl是一個帶控件模板的成熟控件(里面包含ControlPresenter)。

      所以我們一般用ControlPresenter。

      ControlTemplate的VisualTree我們講過了,下面看下他的trigger如何運用。

      我們在原來的代碼中增加

      <ControlTemplate.Triggers>
                   <Trigger Property="IsMouseOver" Value="true">
                         <Setter TargetName="ellipse1" Property="Fill" Value="Red"/>
                   </Trigger>
       </ControlTemplate.Triggers>

      當我們把鼠標移上去的時候就會變成如下圖所示:

      image

      發(fā)揮我們的想象力,我們可以根據(jù)ControlTemplate做更多的特效。如下

      <Style TargetType="CheckBox">
                  <Setter Property="Template">
                      <Setter.Value>
                          <ControlTemplate TargetType="CheckBox">
                              <DockPanel>
                                  <ContentPresenter DockPanel.Dock="Left" VerticalAlignment="Center" />
                                  <Grid>
                                      <Grid.ColumnDefinitions>
                                          <ColumnDefinition Width="30"/>
                                          <ColumnDefinition Width="30"/>
                                      </Grid.ColumnDefinitions>
                                      <Rectangle Grid.Column="0" Grid.ColumnSpan="2" Fill="Gray"/>
                                      <TextBlock x:Name="txtBox"  Foreground="White" />
                                  </Grid>
                              </DockPanel>
                              <ControlTemplate.Triggers>
                                  <Trigger Property="IsChecked" Value="True">
                                      <Setter TargetName="txtBox" Property="Grid.Column" Value="1"/>
                                      <Setter TargetName="txtBox" Property="Text" Value="On"/>
                                      <Setter TargetName="txtBox" Property="Background" Value="LightBlue"/>
                                  </Trigger>
                                  <Trigger Property="IsChecked" Value="{x:Null}">
                                      <Setter TargetName="txtBox" Property="Grid.Column" Value="0"/>
                                  </Trigger>
                                  <Trigger Property="IsChecked" Value="false">
                                      <Setter TargetName="txtBox" Property="Grid.Column" Value="0"/>
                                      <Setter TargetName="txtBox" Property="Text" Value="OFF"/>
                                  </Trigger>
                              </ControlTemplate.Triggers>
                          </ControlTemplate>
                      </Setter.Value>
                  </Setter>
              </Style>
      <Grid>
              <CheckBox Width="100" Height="30" Content="Click Me"/>
       </Grid>

      效果圖:點擊之前image點擊之后image

      2、ItemsPanelTemplate

      ItemsPanelTemplate在MSDN的解釋是:ItemsPanelTemplate 指定用于項的布局的面板。 GroupStyle 具有一個類型為 ItemsPanelTemplate 的 Panel 屬性。 ItemsControl 類型具有一個類型為ItemsPanelTemplate 的 ItemsPanel 屬性。

      我們先講ItemTemplate。它一般用在多個內(nèi)容控件的模板。比如ListBox。

      如下看ListBox應用ItemTemplate:

      在xaml中

      <Style TargetType="ListBox">
                  <Setter Property="ItemTemplate">
                      <Setter.Value>
                          <DataTemplate>
                               <Image Source="{Binding UriSource}" Width="100" Height="100"/>
                          </DataTemplate>
                      </Setter.Value>
                  </Setter>
              </Style>

        <ListBox x:Name="listBox" />

      在后臺代碼我們給它一些圖片來填充這個ListBox.

       public partial class ListBoxUserControl : UserControl
          {
              public ListBoxUserControl()
              {
                  InitializeComponent();
                  listBox.ItemsSource = LoadImages();
              }
      
              public List<BitmapImage> LoadImages()
              {
                  List<BitmapImage> bitmapImages=new List<BitmapImage>();
                  DirectoryInfo directoryInfo = new DirectoryInfo(@"E:\WPFDEMO\ControlTest\ControlTest\Images");
                  foreach (var item in directoryInfo.GetFiles("*.jpg"))
                  {
                      Uri uri=new Uri(item.FullName);
                      bitmapImages.Add(new BitmapImage(uri));
                  }
                  return bitmapImages;
              }
          }
      

      image每一張圖片就是一個Item。

      我們?nèi)绻胱寛D片以橫向顯示。一開始我以為用StackPanel的Orientation=”Horiziontal”,發(fā)現(xiàn)犯了個錯誤。這樣設置是現(xiàn)在把Items中某一個item中的內(nèi)容水平顯示啊。這時就要用到ItemsPanelTemplate這個模板了。我們在ListBox的樣式中增加如下紅色區(qū)域的代碼:

       <Style TargetType="ListBox">
                  <Setter Property="ItemTemplate">
                      <Setter.Value>
                          <DataTemplate>
                              <StackPanel Orientation="Horizontal">
                                  <Image Source="{Binding UriSource}" Width="100" Height="100"/>
                                  <TextBlock Text="qq" Background="Red"/>
                              </StackPanel>
                          </DataTemplate>
                      </Setter.Value>
                  </Setter>
                 

      <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <StackPanel /> </ItemsPanelTemplate> </Setter.Value> </Setter>

              </Style>


      這里我在DataTemplate中加了StackPanel 為了說明加在這里的效果只是區(qū)分:Items整體橫向和Item中內(nèi)容的區(qū)別。

      image

      現(xiàn)在我們要想讓布局可以隨著窗體寬度變化,我們只要把ItemsPanelTemplate中的StackPanel 改成WrapPanel,并且設置ListBox的ScrollViewer.HorizontalScrollBarVisibility="Disabled",這樣才可以看到效果。

      image

      ControlTemplate之 ItemsPresenter和ContentPresenter

      我們先構造一個TreeView

      xaml中:

      在開始加個Loaded="UserControl_Loaded"

      <Grid>
              <TreeView x:Name="treeview" />
      </Grid>

      后臺代碼中:

        public class Node
          {
              private IList<Node> _childNodes;
              private string _name;
              public Node()
              {}
              public Node(string name)
              {
                  _name = name;
              }
              public string Name
              {
                  get { return _name; }
                  set { _name = value; }
              }
      
              public IList<Node> ChildNodes
              {
                  get
                  {
                      if (_childNodes==null)
                          _childNodes=new List<Node>();
                      return _childNodes;
                  }
                 
              }
          }
      
      
      public partial class TreeViewUserControl : UserControl
          {
              public TreeViewUserControl()
              {
                  InitializeComponent();
              }
      
              private void UserControl_Loaded(object sender, RoutedEventArgs e)
              {
                  treeview.PreviewKeyDown += (o,a) => { a.Handled = true; };
                  PopulateTreeView();
              }
              void PopulateTreeView()
              {
                  Node rootNode=new Node("GrandFather");
                  for (int i = 0; i < 2; i++)
                  {
                      Node child=new Node("Father");
                      rootNode.ChildNodes.Add(child);
                      for (int j = 0; j < 3; j++)
                      {
                          Node child2=new Node("Son");
                          child.ChildNodes.Add(child2);
                      }
                  }
      
                  Node dummy=new Node();
                  dummy.ChildNodes.Add(rootNode);
                  treeview.ItemsSource = dummy.ChildNodes;
              }
      
             
      
          }
      

      沒有任何樣式的TreeView

      image

      下面我們?nèi)绾芜\用ItemsPresenter和ContentPresenter來添加樣式。來實現(xiàn)下面這幅圖的效果

      image
      在TreeView中ItemsPresenter和ContentPresenter是什么關系:ContentPresenter是用來顯示TreeView中Item的內(nèi)容 。ItemsPresenter是用來顯示它的子項(Item的子項,也就是說child’s Items)。

      <Style TargetType="TreeViewItem">
              <Style.Resources>
                  <LinearGradientBrush x:Key="ItemAreaBrush" StartPoint="0,0.5" EndPoint="0.5,1">
                      <GradientStop Offset="0" Color="#66000000"/>
                      <GradientStop Offset="1" Color="#22000000"/>
                  </LinearGradientBrush>
                  <LinearGradientBrush x:Key="SelectedItemAreaBrush" StartPoint="0.5, 0" EndPoint="0.5, 1">
                      <GradientStop Color="Orange" Offset="0" />
                      <GradientStop Color="OrangeRed" Offset="1" />
                  </LinearGradientBrush>
                  <LinearGradientBrush x:Key="ItemBorderBrush" StartPoint="0.5, 0" EndPoint="0.5, 1">
                      <GradientStop Color="LightGray" Offset="0" />
                      <GradientStop Color="Gray" Offset="1" />
                  </LinearGradientBrush>
                  <LinearGradientBrush x:Key="SelectedItemBorderBrush" StartPoint="0.5, 0" EndPoint="0.5, 1">
                      <GradientStop Color="Yellow" Offset="0" />
                      <GradientStop Color="Black" Offset="1" />
                  </LinearGradientBrush>
                  <DropShadowBitmapEffect x:Key="DropShadowEffect"/>
              </Style.Resources>
              <Setter Property="Template">
                  <Setter.Value>
                      <ControlTemplate TargetType="TreeViewItem">
                          <Grid Margin="2">
                              <Grid.RowDefinitions>
                                  <RowDefinition Height="auto"/>
                                  <RowDefinition Height="*"/>
                              </Grid.RowDefinitions>
                              <Border x:Name="border" Background="{StaticResource ResourceKey=ItemAreaBrush}" 
                                      BorderBrush="{StaticResource ItemBorderBrush}" BorderThickness="1" CornerRadius="8" Padding="6">
                                  <ContentPresenter  ContentSource="Header" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                              </Border>
                              <ItemsPresenter Grid.Row="1"/>
                          </Grid>
                          <ControlTemplate.Triggers>
                                  <Trigger Property="IsSelected" Value="true">
                                      <Setter TargetName="border" Property="Panel.Background" Value="{StaticResource SelectedItemAreaBrush}"/>
                                  </Trigger>
                          </ControlTemplate.Triggers>
                      </ControlTemplate>
                  </Setter.Value>
              </Setter>
              <Setter Property="ItemsPanel">
                  <Setter.Value>
                      <ItemsPanelTemplate>
                          <StackPanel  Orientation="Horizontal" HorizontalAlignment="Center" IsItemsHost="True"/>
                      </ItemsPanelTemplate>
                  </Setter.Value>
              </Setter>
              
          </Style>
      

      看紅色代碼的部分,這里ContentPresenter顯示了父容器的Header的內(nèi)容,比如GrandFather,Father,Son.而ItemsPresenter則是否讓他顯示其子元素。比如GrandFather的子元素為Father,沒有設置<ItemsPresenter Grid.Row="1"/> 的話。子元素Father是不會顯示的。

      這里為了突出層次化,運用了ItemsPanelTemplate。最后我們在資源里引用這個樣式。

      <UserControl.Resources>
              <ResourceDictionary>
                  <ResourceDictionary.MergedDictionaries>
                      <ResourceDictionary Source="/Controls/TreeViewItemStyle.xaml"/>
                  </ResourceDictionary.MergedDictionaries>
                  <HierarchicalDataTemplate DataType="{x:Type controls:Node}" ItemsSource="{Binding ChildNodes}">
                      <TextBlock Text="{Binding Name}"/>
                  </HierarchicalDataTemplate>
              </ResourceDictionary>
          </UserControl.Resources>
      

      3、DataTemplate和HierarchicalDataTemplate

      DataTemplate就是顯示綁定數(shù)據(jù)對象的模板。
      HierarchicalDataTemplate繼承于DataTemplate,它專門對TreeViewItemMenuItem的一些數(shù)據(jù)對象的綁定。

      想了解下DataTemplate和HierarchicalDataTemplate,就看以上的例子吧。他們中只要有控件的綁定都會用到。想了解的更深一步,請看下南柯之石的這篇文章。

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約