WPF 상세 템 플 릿
63778 단어 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"/>
결과:
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>
이제 내용 이 나 왔어요.
콘 텐 츠 컨트롤 이 control 에 계승 되 는 것 을 살 펴 보 겠 습 니 다. MSDN 을 사용 하면 단일 콘 텐 츠 를 포함 하 는 컨트롤, 콘 텐 츠 컨트롤 은 모든 유형의 공공 언어 실행 라 이브 러 리 대상 을 포함 할 수 있 습 니 다.아래 ContentControl 도표 입 니 다.
성능 을 향상 시 키 기 위해 서 우 리 는 하나의 controlPresenter 로 ContentControl 을 대체 할 수 있 습 니 다. 효과 가 똑 같 습 니 다. 그러면 그들 은 어떤 차이 가 있 습 니까?
ControlPresenter 라 는 종 류 를 보 세 요. Freamework Element 에 계승 되 었 습 니 다. 다음 그림 입 니 다.
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>
우리 가 마 우 스 를 올 릴 때 아래 그림 과 같이 변 한다.
우리 의 상상력 을 발휘 하면 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>
효과 도: 클릭 하기 전
클릭 후
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;
}
}
모든 그림 은 하나의 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 가로 만 구분 합 니 다.
이제 창 너비 에 따라 레이아웃 을 바 꿀 수 있 도록 하려 면 Items Panel Template 의 StackPanel 을 WrapPanel 로 바 꾸 고 Listbox 의 ScrollViewer. Horizontal ScrollBarVisibility = "Disabled" 를 설정 해 야 효 과 를 볼 수 있 습 니 다.
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 도 없습니다.
다음은 Items Presenter 와 ContentPresenter 를 활용 하여 스타일 을 추가 하 는 방법 입 니 다.아래 그림 의 효 과 를 실현 하 겠 습 니 다.
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
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
MaterialDesign의 ComboBox HasClearButton 크기 변경WPF MaterialDesign은 편리하지만 때로는 표시가 너무 크거나 약간 사용하기 쉽습니다. ComboBox를 사용할 때 선택한 버튼을 지우려면 지우기 버튼을 표시할 수 있습니다. 아래와 같은 표시가 됩니다 다...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.