WPF中ControlTemplate,ItemsPanelTemplate ,DataTemplate


       使用WPF的過程中,設計界面常會用到幾種模板,如ControlTemplate, ItemsPanelTemplate 和 DataTemplate, 在這里對每一個介紹一番。
   ControlTemplate
       說明:用以控件控件的外觀,如下代碼就是用來設計一個自定義的按鈕樣式。
        <Style TargetType="Button">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border BorderThickness="1" BorderBrush="Red" CornerRadius="5">
                            1<!--<ContentControl VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}"
                                            ContentTemplate="{TemplateBinding ContentTemplate}"/>-->
                            2<!--<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>-->
                            3<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
     運行結果:
     注意點:
     示例代碼中1,2,3片段用那一個都是可以的,相同的結果,其中2,3是等價的,使用ContentPresenter時會隱式的進行TemplateBinding,這的確是經常需要的。其中1最終也是使用了ContentPresenter用來呈現內容,所以不建議使用ContentControl,有點大才小用的趕腳。實際上也是如此,ContentControl中包含ContentPresenter.
   ItemsPanelTemplate
     說明:用以定義集合控件的容器外觀,如ListBox,Combox 等等,這里使用一個自定義的listBox用以說明,其默認外觀是上下排列,這里修改成橫向排列。
  示例代碼:
<ListBox HorizontalAlignment="Left" Height="100" Margin="49,111,0,0" VerticalAlignment="Top" Width="100">
            <system:String>abc</system:String>
            <system:String>def</system:String>
            <system:String>hij</system:String>
        </ListBox>
        <ListBox HorizontalAlignment="Left" Height="31" Margin="184,111,0,0" VerticalAlignment="Top" Width="100">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"></StackPanel>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <system:String>abc</system:String>
            <system:String>def</system:String>
            <system:String>hij</system:String>
        </ListBox>
 運行結果:  
    
 
      DataTemplate
     說明:以命名來看,是用來表現數據外觀的,先上一個簡單的示例:
   public class Person
    {
        public string Name { get; set; }
        public string Des { get; set; }
    }

<wpfApplication1:Person x:Key="p1" Name="P1" Des="Girl"/>
       
        <DataTemplate x:Key="dt1" DataType="wpfApplication1:Person">
            <TextBlock>
                    <Run Text="{Binding Name}"/>
                    <Run Text=":"/>
                    <Run Text="{Binding Des}"/>
            </TextBlock>
        </DataTemplate>

<Button Content="{StaticResource p1}" HorizontalAlignment="Left" Margin="204,219,0,0" VerticalAlignment="Top" Width="193" Height="36"/>
        <Button Content="{StaticResource p1}" ContentTemplate="{StaticResource dt1}"  HorizontalAlignment="Left" Margin="204,275,0,0" VerticalAlignment="Top" Width="193" Height="35"/>

  運行結果:

   
     解析:數據模板用來呈現數據,在這個例子中,直接將Button的內容指向一個Person類,若不指定其DataTemplate,則Button的內容只會簡單的顯示為綁定對象的ToString內容,指定了Person的顯示方式,則會按照預期的想法進行呈現。
HierarchicalDataTemplate
     該數據模板主要應用於比較復雜的樹形結構中,HierarchicalDataTemplate從DataTemplate繼承而來,其用法也相當的簡單,這里給一個簡單的示例即可。
     代碼:
 
<DockPanel.Resources>
            <HierarchicalDataTemplate DataType     = "{x :Type local :Person}"
                                ItemsSource = "{Binding Path=Persons}">
                <TextBlock Text ="{Binding Path =Name}"/>
            </HierarchicalDataTemplate>
 
            <HierarchicalDataTemplate DataType     = "{x :Type local :Child}"
                                ItemsSource = "{Binding Path=Persons}">
                <TextBlock Text ="{Binding Path =Des}"/>
            </HierarchicalDataTemplate>
        </DockPanel.Resources>
        <TreeView x :Name="st">
          
        </TreeView>
 
public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
 
            this.Loaded += MainWindow_Loaded;
        }
 
        private void MainWindow_Loaded( object sender, RoutedEventArgs e)
        {
   
            st.ItemsSource = new List< Person>(){ Person.GetRandomPerson(),Person .GetRandomPerson() };
        }
    }
 
    public class Person
    {
        public string Name { get; set; }
        public string Des { get; set; }
 
        public List< Child> Persons { get; set; }
 
        public static Person GetRandomPerson( int count=0)
        {
            var random = new Random( DateTime.Now.Millisecond);
            var next = random.Next();
            var person = new Person {Name = "name" + next, Des = "des" + next};
            person.Persons = new List< Child>();
            if (count++ < 5)
            {
                for ( int i = 0; i < next % 10; i++)
                {
                    person.Persons.Add( Child.GetRandomPerson(count));
                }
            }
            return person;
        }
    }
 
    public class Child
    {
        public string Name { get; set; }
        public string Des { get; set; }
        public List< Child> Persons { get; set; }
        public static Child GetRandomPerson( int count = 0)
        {
            var random = new Random( DateTime.Now.Millisecond);
            var next = random.Next();
            var person = new Child { Name = "name" + next, Des = "des" + next };
            person.Persons = new List< Child>();
            if (count++ < 2)
            {
                for ( int i = 0; i < next % 10; i++)
                {
                    person.Persons.Add(GetRandomPerson(count));
                }
            }
            return person;
        }
    }
     運行結果:
 
StyleSelector and DataTemplateSelector
     考慮到這樣一種場景,集合控件需要根據不同的行去設置不同的行樣式及內容呈現方式,這就用到了這兩個Selector,需要繼承這兩個類,定義自己需要的效果。同樣的,以代碼作為示例,並演示相關結果
     Code:
class MyStyleSelector : StyleSelector
    {
        public Style StyleContainsO { get; set; }
        public Style StyleOther { get; set; }
 
        public override Style SelectStyle( object item, DependencyObject container)
        {
            Style re;
 
            ItemsControl itmesControl = ItemsControl.ItemsControlFromItemContainer(container);
 
            var index = itmesControl.ItemContainerGenerator.IndexFromContainer(container);
 
            if (index%3==0)
                re = StyleContainsO;
            else
            {
                re = StyleOther;
            }
            return re;
        }
    }
 
    class MyDataTemplateSelector : DataTemplateSelector
    {
        public DataTemplate DataContainsO { get ; set ; }
        public DataTemplate DataOther { get ; set ; }
 
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            if (item.ToString().Contains( "O"))
                return DataContainsO;
            return DataOther;
         
        }
    }
 
    <Window.Resources >
        <!-- 數據 -->
        <x: Array xmlns: sys="clr-namespace:System;assembly=mscorlib"
             Type="sys:String"
             x:Key ="array">
            <sys: String>Op</sys :String>
            <sys: String>Kip</sys :String>
            <sys: String>Opp</sys :String>
            <sys: String>Oms</sys :String>
            <sys: String>Kmp</sys :String>
        </x: Array>
 
        <!-- 自定義3種樣式 -->
        <Style x :Key="st1" TargetType="ListBoxItem">
            <Setter Property ="Background" Value="Gray" />
            <Setter Property ="HorizontalContentAlignment" Value="Center" />
        </Style>
 
        <Style x :Key="st2" TargetType="ListBoxItem">
            <Setter Property ="Background" Value="DarkOliveGreen" />
            <Setter Property ="HorizontalContentAlignment" Value="Center" />
        </Style>
 
        <DataTemplate x :Key="d1">
            <TextBlock Text ="{Binding Mode =OneWay}"></TextBlock>
        </DataTemplate>
 
        <DataTemplate x :Key="d2">
            <TextBox Text ="{Binding Mode =OneWay}"></TextBox>
        </DataTemplate>
 
        <!-- XML命名空間loc是MyStyleSelector的CLR命名空間 -->
        <local: MyStyleSelector
                         x:Key ="mySelector"
                         StyleContainsO="{StaticResource st1}"
                         StyleOther="{StaticResource st2}"/>
 
        <local: MyDataTemplateSelector
                         x:Key ="myDataSelector"
                         DataContainsO="{StaticResource d1}"
                         DataOther="{StaticResource d2}"/>
    </Window.Resources >
    <ListBox ItemsSource="{StaticResource array}" ItemContainerStyleSelector="{ StaticResource mySelector}" ItemTemplateSelector="{ StaticResource myDataSelector}">
    </ListBox >

運行結果:

     
  
  最后,文章寫的比較亂,也可以說不算是文章,代碼比較多,如果對您有所幫助,那本人也很欣慰,新手上路,歡迎各位吐槽~~
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM