WPF 상세 템 플 릿

63778 단어 WPF
이 블 로 그 는 내 가 WPF 템 플 릿 을 다시 이해 할 때 쓴 것 이다. 사실은 내 가 쓴 것 이 아니 라 내 가 자주 보 는 것 이다. 나 는 단지 안에 있 는 몇 개의 문장 을 수 정 했 을 뿐이다. 원문 이 매우 좋 고 가슴 에 스 며 들 기 때문에 자신의 블 로그 에 옮 겨 싣 고 원문의 주소 도 함께 지불 했다.
http://www.cnblogs.com/dingli/archive/2011/07/20/2112150.html
http://www.cnblogs.com/lxblog/archive/2012/10/16/2726826.html
WPF 에는 3 대 템 플 릿 인 Control Template, Items Panel Template, DataTemplate 가 있 습 니 다. 그 중에서 Control Template 와 Items Panel Template 는 컨트롤 템 플 릿 이 고 DataTemplate 는 데이터 템 플 릿 입 니 다. 그들 은 모두 Framework Template 추상 류 에서 파생 되 었 습 니 다.
1、ControlTemplate
controlTemplate: 컨트롤 템 플 릿 은 주로 두 가지 중요 한 속성 이 있 습 니 다. VisualTree 내용 속성 과 Triggers 트리거 입 니 다.VisualTree (시각 트 리) 란 우리 가 그린 컨트롤 을 보 여 주 는 것 입 니 다.Triggers 는 우리 의 시각 트 리 에 있 는 요 소 를 변화 시 킬 수 있다.일반적으로 단일 콘 텐 츠 컨트롤 에 사 용 됩 니 다.
버튼 템 플 릿 을 그 려 서 예 를 들 어 설명 합 니 다.
  <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 속성 (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>

 
 
이제 내용 이 나 왔어요.
image
콘 텐 츠 컨트롤 이 control 에 계승 되 는 것 을 살 펴 보 겠 습 니 다. MSDN 을 사용 하면 단일 콘 텐 츠 를 포함 하 는 컨트롤, 콘 텐 츠 컨트롤 은 모든 유형의 공공 언어 실행 라 이브 러 리 대상 을 포함 할 수 있 습 니 다.아래 ContentControl 도표 입 니 다.
image
성능 을 향상 시 키 기 위해 서 우 리 는 하나의 controlPresenter 로 ContentControl 을 대체 할 수 있 습 니 다. 효과 가 똑 같 습 니 다. 그러면 그들 은 어떤 차이 가 있 습 니까?
ControlPresenter 라 는 종 류 를 보 세 요. Freamework Element 에 계승 되 었 습 니 다. 다음 그림 입 니 다.
image
controlPresenter 는 일반적으로 내용 자리 차지 문자 라 고 부른다.그래서 저희 가 볼 수 있어 요.
< ContentPresenter Vertical Alignment = "Center" Horizontal Alignment = "Center" / > 대신 < ContentControl Vertical Alignment = "Center" Horizontal Alignment = "Center" Content = "{Template Binding Content}" / >.콘 텐 츠 바 인 딩 부모 용기 가 없습니다. controlPresenter 는 암시 적 인 콘 텐 츠 = "{Template Binding 콘 텐 츠}" 가 있 기 때문에 쓸 수도 있 고 쓰 지 않 아 도 됩 니 다.
그들의 기 류 를 통 해 알 수 있 듯 이 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
우리 의 상상력 을 발휘 하면 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
Items Panel Template 는 MSDN 에서 Items Panel Template 가 항목 의 레이아웃 에 사용 할 패 널 을 지정 합 니 다.GroupStyle 아 이 템 스 패 널 템 플 릿 Panel 의 속성 을 가지 고 있 습 니 다.ItemsControl 유형 은 Items Panel Template ItemsPanel 속성 을 가지 고 있 습 니 다.
아 이 템 템 템 플 릿 부터 말씀 드 리 겠 습 니 다.그것 은 일반적으로 여러 콘 텐 츠 컨트롤 의 템 플 릿 에 사용 된다.예 를 들 면 리스트 박스.
다음은 ListBox 응용 항목 템 플 릿 을 보십시오.
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 이다.우리 가 그림 을 가로로 표시 하려 면처음에 저 는 StackPanel 의 Orientation = "Horizontal" 을 사용 하 는 줄 알 았 습 니 다. 실행 할 때 이것 이 정확 하지 않 은 것 을 발 견 했 습 니 다. 이러한 설정 은 Items 중의 한 Item 중의 모든 내용 을 수평 으로 배치 하 는 것 이 고 그림 은 수직 으로 배열 하 는 것 입 니 다. 이 아 이 템 은 현재 하나의 Image 와 Textblock 을 포함 하고 있 기 때 문 입 니 다. 이 두 개 는 하나의 StackPanel 에 놓 인 것 이기 때문에 Horizontal 을 설 치 했 습 니 다.그러면 Image 와 TextBlock 은 수평 이지 만 전체적으로 변화 가 없습니다. 예상 한 결 과 를 얻 으 려 면 Items Panel Template 라 는 템 플 릿 을 사용 해 야 합 니 다. Listbox 스타일 에 다음 과 같은 빨간색 구역 의 코드 를 추가 합 니 다.
 <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  Orientation="Horizontal" /> </ItemsPanelTemplate> </Setter.Value> </Setter>



        </Style>

 
 
여기에 DataTemplate 에 StackPanel 을 추가 하여 여기에 추 가 된 효 과 를 설명 하기 위해 서 는 하나의 item 가로 와 전체 items 가로 만 구분 합 니 다.
image
이제 창 너비 에 따라 레이아웃 을 바 꿀 수 있 도록 하려 면 Items Panel Template 의 StackPanel 을 WrapPanel 로 바 꾸 고 Listbox 의 ScrollViewer. Horizontal ScrollBarVisibility = "Disabled" 를 설정 해 야 효 과 를 볼 수 있 습 니 다.
image ControlTemplate 의 Items Presenter 와 ContentPresenter
트 리 뷰 를 만들어 보도 록 하 겠 습 니 다.
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
다음은 Items Presenter 와 ContentPresenter 를 활용 하여 스타일 을 추가 하 는 방법 입 니 다.아래 그림 의 효 과 를 실현 하 겠 습 니 다.
image TreeView 에서 Items Presenter 와 ContentPresenter 는 어떤 관계 입 니까? ContentPresenter 은 TreeView 에서 Item 의 내용 을 표시 하 는 데 사 용 됩 니 다.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 내용 을 보 여 줍 니 다. 예 를 들 어 GrandFather, Father, Son. 그리고 Items Presenter 는 그 에 게 하위 요 소 를 표시 하 게 할 지 여부 입 니 다.예 를 들 어 GrandFather 의 하위 요 소 는 Father 이 고 < Items Presenter Grid. Row = "1" / > 을 설정 하지 않 았 다 면.하위 요소 인 Father 는 표시 되 지 않 습 니 다.
여기 에는 차원 화 를 강조 하기 위해 아 이 템 패 널 템 플 릿 을 활용 했다.마지막 으로 우 리 는 자원 에서 이 스타일 을 인용 합 니 다.
<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 는 바 인 딩 데이터 대상 을 표시 하 는 템 플 릿 입 니 다.HierarchicalDataTemplate 는 DataTemplate 에 계승 되 어 TreeViewItem 또는 MenuItem 의 일부 데이터 대상 에 대한 연결 입 니 다.
DataTemplate 와 HierarchicalDataTemplate 에 대해 알 고 싶 으 면 이상 의 예 를 보 세 요.그들 중 에는 컨트롤 의 연결 만 있 으 면 모두 사용 할 것 이다.더 깊이 알 고 싶 으 시 면 남 가 의 돌 의 이 글 을 보 세 요.
HierarchicalDataTemplate 에 대해 서 는 다음 을 참조 할 수 있 습 니 다. http://www.cnblogs.com/lxblog/archive/2012/10/24/2737876.html

좋은 웹페이지 즐겨찾기