글쎄, 불행히도 WPF가 작동하는 방식입니다. 기본 컨트롤의 스타일을 변경하려면 (위에 게시 한 것처럼) 일련의 스타일 선언을 사용하여 작업하고 변경해야합니다.
Expression Blend를 사용하면 스타일을 쉽게 수정하는 데 사용할 수있는 UI 디자이너가 있으므로 쉽게 사용할 수 있습니다. 그러나 장면 뒤에는 여전히 스타일 선언이 있습니다. 예를 들어 블렌드를 사용하여 요구 사항을 처리하는 방법은 다음과 같습니다.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication1.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Window.Resources>
<Style x:Key="TreeViewItemFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<PathGeometry x:Key="TreeArrow" Figures="M0,0 L0,6 L6,0 z"/>
<Style x:Key="ExpandCollapseToggleStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Width" Value="16"/>
<Setter Property="Height" Value="16"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Background="Transparent" Height="16" Padding="5,5,5,5" Width="16">
<Image x:Name="PART_Image" Source="Image1.jpg"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="False"/>
<Trigger Property="IsMouseOver" Value="True"/>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Source" TargetName="PART_Image" Value="Image2.jpg"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="1,0,0,0"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="19" Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<ToggleButton x:Name="Expander" ClickMode="Press" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ExpandCollapseToggleStyle}"/>
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="1" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ItemsPresenter x:Name="ItemsHost" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="Visibility" TargetName="Expander" Value="Hidden"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="VirtualizingStackPanel.IsVirtualizing" Value="true">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<TreeView HorizontalAlignment="Left" Margin="8,8,0,105" Width="196">
<TreeViewItem Header="Item1">
<TreeViewItem Header="Item2"/>
</TreeViewItem>
</TreeView>
</Grid>
</Window>
어쨌든이 도움이 되었기를 바랍니다.
는 편집 :
좋아, 내가 게시 된 코드를 훨씬 당신이 당신의 예에서 무엇을 게시처럼 것으로 나타났습니다. 하지만 위의 수정을 위해 표현식을 사용했습니다. 그리고 Blend 사용 여부와 상관없이 여러 가지 스타일 선언으로 작업해야합니다. =)
EDIT2 :
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="300" Width="300">
<Window.Resources>
<HierarchicalDataTemplate x:Key="treeTemplate"
ItemsSource="{Binding SubItems}">
<TextBlock Text="{Binding Name}"/>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
<Style x:Key="ExpandCollapseToggleStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Width" Value="16"/>
<Setter Property="Height" Value="16"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Background="Transparent" Height="16" Width="16">
<Image x:Name="PART_Image" Source="{Binding ImageSource}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="customTreeItemStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="1,0,0,0"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="19" Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<ToggleButton x:Name="Expander" ClickMode="Press" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ExpandCollapseToggleStyle}"/>
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="1" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ItemsPresenter x:Name="ItemsHost" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="Visibility" TargetName="Expander" Value="Hidden"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="VirtualizingStackPanel.IsVirtualizing" Value="true">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<TreeView x:Name="tree"
ItemTemplate="{StaticResource treeTemplate}"
ItemContainerStyle="{StaticResource customTreeItemStyle}"/>
</Window>
코드 숨김
Window.xaml :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private List<ViewModel> items = new List<ViewModel>();
public MainWindow()
{
InitializeComponent();
ViewModelImpl1 vm1 = new ViewModelImpl1() { Name = "VM1" };
vm1.SubItems.Add("SubItem1");
vm1.SubItems.Add("SubItem2");
vm1.SubItems.Add("SubItem3");
ViewModelImpl1 vm2 = new ViewModelImpl1() { Name = "VM2" };
vm2.SubItems.Add("SubItem1");
vm2.SubItems.Add("SubItem2");
vm2.SubItems.Add("SubItem3");
vm2.SubItems.Add("SubItem4");
ViewModelImpl2 vm3 = new ViewModelImpl2() { Name = "VM3" };
vm3.SubItems.Add("SubItem1");
items.Add(vm1);
items.Add(vm2);
items.Add(vm3);
tree.ItemsSource = items;
}
}
}
ViewModels
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace WpfApplication2
{
public abstract class ViewModel : INotifyPropertyChanged
{
private List<string> subItems = new List<string>();
public List<string> SubItems
{
get { return this.subItems; }
}
private string name;
public string Name
{
get { return this.name; }
set
{
this.name = value;
this.OnPropertyChanged("Name");
}
}
private bool isExpanded;
public bool IsExpanded
{
get { return this.isExpanded; }
set
{
this.isExpanded = value;
this.OnPropertyChanged("IsExpanded");
UpdateImageSource();
}
}
private string imageSource;
public string ImageSource
{
get
{
if (this.imageSource == null)
UpdateImageSource();
return this.imageSource;
}
protected set
{
this.imageSource = value;
this.OnPropertyChanged("ImageSource");
}
}
protected abstract void UpdateImageSource();
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
#endregion
}
public class ViewModelImpl1 : ViewModel
{
protected override void UpdateImageSource()
{
if (this.IsExpanded)
this.ImageSource = "pack://application:,,,/Images/bell1.png";
else
this.ImageSource = "pack://application:,,,/Images/bell2.png";
}
}
public class ViewModelImpl2 : ViewModel
{
protected override void UpdateImageSource()
{
if (this.IsExpanded)
this.ImageSource = "pack://application:,,,/Images/star1.png";
else
this.ImageSource = "pack://application:,,,/Images/star2.png";
}
}
}
내가 제대로 내 문제를 설명 수도, 나는 죄송합니다. 위의 스타일과 필요성을 이해합니다. 그러나 필요한 것은 다른 트리 노드에 대해 다른 이미지를 사용하는 것입니다. 예 : "항목 1"은 Image1.jpg 및 Image2.jpg (축소/확장 용)를 사용하고 "항목 2"는 축소/확장 용 Image3.jpg 및 Image4.jpg를 사용합니다. 여러 개의 TreeViewItem 스타일과 ExpandCollapseToggleStyle 스타일 (사용중인 이미지 당 하나씩)을 만드는 것보다 간단한 방법이 있는지 궁금합니다. 아마도 DependencyProperty 나 바인딩을 사용하여 코드의 이미지를 변경할 수 있습니까? – Travis
위의 Edit2를 참조하십시오.코드 예제는 필요한 것을 거의 수행합니다. TreeViewItem에 ViewModel을 사용해야했습니다. ViewModel에는 TreeViewItem의 토글 버튼에서 사용할 이미지를 결정하는 속성이 있습니다. 희망이 도움이됩니다. – ASanch
늦어서 죄송합니다. 잠시 새 프로젝트에 참여했습니다. 도움을 주셔서 대단히 감사합니다. 훌륭한 스타일 인 것 같습니다. 스타일에 관해서는 나에게 훌륭한 학습 도구였습니다. 분명히, 나는 당신을 투표하는 데 충분한 명성이 없다. 나는 사과한다. 바라기를, 나는 충분히 얻을 때 돌아와 할 수 있습니다. 다시 도움 주셔서 감사합니다. – Travis