none
关于WPF Treeview 节点展开和收缩标志的位置问题 RRS feed

  • 问题

  • 各位老师:
    WPF Treeview 可以通过控件或数据模板自定义数据节点的展示内容,我的想法是为节点增加一或若干行说明性的文字。现在,通过模板实现了。但是,

    节点的展开和收缩标志位置也随之变化了(见中间的视图)。我的问题是:有什么办法可以让这个展开和收缩标志位置保持不变,始终在节点首行,即

    不管一个节点有多少说明行都保持这个标志位置不变(见右边视图)。谢谢。

    附1、节点增加说明行前后的xmal代码片段。

    通常的节点模板:
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                        <TextBlock Text="{Binding Name}" />
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>

    增加说明行的节点模板:
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                        <StackPanel>
                            <TextBlock Text="{Binding Name}" />
                            <TextBlock Text="本节点说明行(可能多行)"/>
                        </StackPanel>
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>


    ly_he

    2015年10月9日 7:15

答案

  • 你好,

    你这样只是在HierarchicalDataTemplate中用一个StackPanel包围起来是不行的,你需要自定义TreeViewItem的样式,因为小箭头和节点头的文本在TreeViewItem的样式里不是包含在一起的,你可以在Blend中修改它的样式模板,下面是我修改后的样式,重点看我加粗的部分:

    <Window.Resources>
    		<Style x:Key="TreeViewItemFocusVisual">
    			<Setter Property="Control.Template">
    				<Setter.Value>
    					<ControlTemplate>
    						<Rectangle/>
    					</ControlTemplate>
    				</Setter.Value>
    			</Setter>
    		</Style>
    		<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Checked.Fill" Color="#FF595959"/>
    		<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Checked.Stroke" Color="#FF262626"/>
    		<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Stroke" Color="#FF27C7F7"/>
    		<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Fill" Color="#FFCCEEFB"/>
    		<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Checked.Stroke" Color="#FF1CC4F7"/>
    		<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Checked.Fill" Color="#FF82DFFB"/>
    		<PathGeometry x:Key="TreeArrow" Figures="M0,0 L0,6 L6,0 z"/>
    		<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Fill" Color="#FFFFFFFF"/>
    		<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Stroke" Color="#FF818181"/>
    		<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">
    							<Path x:Name="ExpandPath" Data="{StaticResource TreeArrow}" Fill="{StaticResource TreeViewItem.TreeArrow.Static.Fill}" Stroke="{StaticResource TreeViewItem.TreeArrow.Static.Stroke}">
    								<Path.RenderTransform>
    									<RotateTransform Angle="135" CenterY="3" CenterX="3"/>
    								</Path.RenderTransform>
    							</Path>
    						</Border>
    						<ControlTemplate.Triggers>
    							<Trigger Property="IsChecked" Value="True">
    								<Setter Property="RenderTransform" TargetName="ExpandPath">
    									<Setter.Value>
    										<RotateTransform Angle="180" CenterY="3" CenterX="3"/>
    									</Setter.Value>
    								</Setter>
    								<Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.Static.Checked.Fill}"/>
    								<Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.Static.Checked.Stroke}"/>
    							</Trigger>
    							<Trigger Property="IsMouseOver" Value="True">
    								<Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Stroke}"/>
    								<Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Fill}"/>
    							</Trigger>
    							<MultiTrigger>
    								<MultiTrigger.Conditions>
    									<Condition Property="IsMouseOver" Value="True"/>
    									<Condition Property="IsChecked" Value="True"/>
    								</MultiTrigger.Conditions>
    								<Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Checked.Stroke}"/>
    								<Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Checked.Fill}"/>
    							</MultiTrigger>
    						</ControlTemplate.Triggers>
    					</ControlTemplate>
    				</Setter.Value>
    			</Setter>
    		</Style>
    		<Style x:Key="TreeViewItemStyle1" 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" Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" 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.InactiveSelectionHighlightBrushKey}}"/>
    								<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>
    							</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="VirtualizingPanel.IsVirtualizing" Value="true">
    					<Setter Property="ItemsPanel">
    						<Setter.Value>
    							<ItemsPanelTemplate>
    								<VirtualizingStackPanel/>
    							</ItemsPanelTemplate>
    						</Setter.Value>
    					</Setter>
    				</Trigger>
    			</Style.Triggers>
    		</Style>
    	</Window.Resources>
    <TreeView Style="{DynamicResource TreeViewStyle1}"/>



    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2015年10月12日 3:34
    版主
  • 你好,

    对于已经解决的问题,请及时“标记为答案”,如果有新的问题,请重新开个新帖去提问。

    谢谢理解!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • 已标记为答案 ly_he 2015年11月19日 12:26
    2015年11月7日 8:58
    版主

全部回复

  • 你好,

    你这样只是在HierarchicalDataTemplate中用一个StackPanel包围起来是不行的,你需要自定义TreeViewItem的样式,因为小箭头和节点头的文本在TreeViewItem的样式里不是包含在一起的,你可以在Blend中修改它的样式模板,下面是我修改后的样式,重点看我加粗的部分:

    <Window.Resources>
    		<Style x:Key="TreeViewItemFocusVisual">
    			<Setter Property="Control.Template">
    				<Setter.Value>
    					<ControlTemplate>
    						<Rectangle/>
    					</ControlTemplate>
    				</Setter.Value>
    			</Setter>
    		</Style>
    		<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Checked.Fill" Color="#FF595959"/>
    		<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Checked.Stroke" Color="#FF262626"/>
    		<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Stroke" Color="#FF27C7F7"/>
    		<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Fill" Color="#FFCCEEFB"/>
    		<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Checked.Stroke" Color="#FF1CC4F7"/>
    		<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Checked.Fill" Color="#FF82DFFB"/>
    		<PathGeometry x:Key="TreeArrow" Figures="M0,0 L0,6 L6,0 z"/>
    		<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Fill" Color="#FFFFFFFF"/>
    		<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Stroke" Color="#FF818181"/>
    		<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">
    							<Path x:Name="ExpandPath" Data="{StaticResource TreeArrow}" Fill="{StaticResource TreeViewItem.TreeArrow.Static.Fill}" Stroke="{StaticResource TreeViewItem.TreeArrow.Static.Stroke}">
    								<Path.RenderTransform>
    									<RotateTransform Angle="135" CenterY="3" CenterX="3"/>
    								</Path.RenderTransform>
    							</Path>
    						</Border>
    						<ControlTemplate.Triggers>
    							<Trigger Property="IsChecked" Value="True">
    								<Setter Property="RenderTransform" TargetName="ExpandPath">
    									<Setter.Value>
    										<RotateTransform Angle="180" CenterY="3" CenterX="3"/>
    									</Setter.Value>
    								</Setter>
    								<Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.Static.Checked.Fill}"/>
    								<Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.Static.Checked.Stroke}"/>
    							</Trigger>
    							<Trigger Property="IsMouseOver" Value="True">
    								<Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Stroke}"/>
    								<Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Fill}"/>
    							</Trigger>
    							<MultiTrigger>
    								<MultiTrigger.Conditions>
    									<Condition Property="IsMouseOver" Value="True"/>
    									<Condition Property="IsChecked" Value="True"/>
    								</MultiTrigger.Conditions>
    								<Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Checked.Stroke}"/>
    								<Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Checked.Fill}"/>
    							</MultiTrigger>
    						</ControlTemplate.Triggers>
    					</ControlTemplate>
    				</Setter.Value>
    			</Setter>
    		</Style>
    		<Style x:Key="TreeViewItemStyle1" 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" Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" 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.InactiveSelectionHighlightBrushKey}}"/>
    								<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>
    							</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="VirtualizingPanel.IsVirtualizing" Value="true">
    					<Setter Property="ItemsPanel">
    						<Setter.Value>
    							<ItemsPanelTemplate>
    								<VirtualizingStackPanel/>
    							</ItemsPanelTemplate>
    						</Setter.Value>
    					</Setter>
    				</Trigger>
    			</Style.Triggers>
    		</Style>
    	</Window.Resources>
    <TreeView Style="{DynamicResource TreeViewStyle1}"/>



    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2015年10月12日 3:34
    版主
  • Xavier Eoro老师,太谢谢您了。我要的正是这个效果。我马上试一试。再次感谢!

    ly_he

    2015年10月15日 10:31
  • Xavier Eoro老师,把您提供的xaml文件的窗体资源代码粘贴上后,出现了几个错误:

    <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>

    错误:无法识别或访问成员“InactiveSelectionHighlightBrushKey”。
    错误:无法找到类型“SystemColors”上的静态成员“InactiveSelectionHighlightBrushKey”。

    <Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
    错误:无法识别或访问成员“IsVirtualizing”。

    不知道什么原因,麻烦您再帮看看。谢谢!


    ly_he

    2015年10月15日 11:01
  • 这种问题一般是有那个dll每天添加引用造成的,你看看是否跟我的一样:

    如果还是有问题,我建议你重新建个项目试一下,并且不一定要粘贴我的代码,你可以在Blend中编辑你的TreeView模板,我的代码是重点让你明白实现你所说的效果要改哪些地方,重点看我代码加粗的部分。


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2015年10月16日 2:18
    版主
  • 尊敬的Xavier Eoro

    感谢您的真诚帮助。我发现,我的上一个问题“检索节点后动态加载”也是您回复的。根据您的思路,那个问题已解决,在此深表谢意。好的,我马上看看这个引用是不是有问题。您说得对,关键需要用blend编辑Treeview模板。因为没有使用过blend。看来,还是要用的。

    ly_he


    ly_he

    2015年10月18日 2:49
  • 你好,

    对于已经解决的问题,请及时“标记为答案”,如果有新的问题,请重新开个新帖去提问。

    谢谢理解!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • 已标记为答案 ly_he 2015年11月19日 12:26
    2015年11月7日 8:58
    版主