WPF TreeViewItem 控件模板的高度不折叠
Height of WPF TreeViewItem controltemplate not collapsing
我有一个问题已经尝试解决了一周,我不仅广泛尝试解决这个问题,而且还在 Whosebug 和其他网站上进行了大量研究以了解如何解决此问题。需要说明的是,我学习 WPF 大约 3 个月左右,来自 WinForms,目前仍处于学习阶段。
这是我的问题。
我有一个要添加到 TreeView 控件的 TreeViewItems。这些 TreeView 项使用创建自定义外观的 Style,我正在尝试实现它,这几乎是整个应用程序的外观。样式使用显式 Setter.Value 反对模板 属性 来创建 TreeView 项目的自定义外观。它有自己的自定义扩展器箭头,绑定到 TreeViewItem header 的 TextBlock header,当然还有一个 ContentPresenter 和一个 ItemsPresenter。还有一个连接到 TreeViewItem 的 IsExpanded 值的触发器,以便在展开或折叠 TreeViewItem 时可以显示或隐藏 ItemsPresenter。除折叠和展开部分外,一切正常。当然,ItemsPresenter 会像它应该的那样隐藏和显示,但是当 IsExpanded 为 false 时,TreeViewItem 本身实际上并没有折叠它的高度。为了说明我的意思,这里有 2 张图片来说明发生了什么。我在样式模板中的网格周围添加了一个绿色边框,以表明单个 TreeViewItem 本身在折叠时没有缩小其 "height"。
展开
Pic of expanded tree view item
崩溃
Pic of collapsed tree view item
如您所见,绿色边框或树视图项目本身在折叠时的高度与展开时的高度相同。这是用于创建 TreeViewItem 自身自定义样式的 XAML。
TreeViewItem 样式XAML代码:
<Style x:Key="TreeViewItemStyle" TargetType="TreeViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeViewItem">
<Border x:Name="MyBorder" BorderThickness="1" BorderBrush="LawnGreen">
<Grid HorizontalAlignment="Left" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="25"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ui:TreeViewItemExpander x:Name="TreeViewItemExpander" Grid.Row="0" Grid.Column="0" IsPointingDown="{TemplateBinding IsExpanded}"/>
<!--This represents the text for the tree view item itself-->
<TextBlock Text="{TemplateBinding Header}" Grid.Row ="0" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Center" Foreground="White"/>
<ContentPresenter x:Name="ContentPresenter" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<ItemsPresenter x:Name="ItemsPresenter" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" Visibility="Hidden"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="ItemsPresenter" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
下面这段代码是我使用样式的方式
<TreeView Style="{StaticResource TreeViewStyle}" Width="200" Margin="419,337,19,328">
<controls:CustomTreeViewItem Header="Folder 1" Style="{StaticResource TreeViewItemStyle}">
<Button Content="Item 1" HorizontalAlignment="Left" VerticalAlignment="Top" Height="20"/>
<Button Content="Item 2" HorizontalAlignment="Left" VerticalAlignment="Top" Height="20"/>
</controls:CustomTreeViewItem>
</TreeView>
感谢任何人可以提供的任何输入或帮助。我希望我已经足够清楚了。
我明白了。我所做的只是在 IsExpanded 触发器中添加一个 setter 以设置 ItemsPresenter 所在的网格行的 属性。我所做的只是将行的高度设置为 0,这实际上隐藏了项目。这是上面代码中应用了更改的触发器本身的代码。
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="Items" Property="Visibility" Value="Visible"/>
<Setter TargetName="ItemsRow" Property="Height" Value="0"/>
</Trigger>
</ControlTemplate.Triggers>
如果其他人有更好的解决方案,我很感兴趣。弄清楚这一点后,我又考虑将行的高度设置为 0 以提供更好的效果,但没有成功。我发现 StoryBoard 是可冻结的,并且在 Style 或 ControlTemplate 内部时被冻结。这意味着如果您希望它具有动画效果,那么项目折叠的动画必须通过代码隐藏实现,或者在每个 TreeViewItem 上单独实现?我相信有更好的方法。如果我知道如何做到这一点,我会更新这个post供大家参考。请随时添加到此 post 更好的解决方案!!
我有一个问题已经尝试解决了一周,我不仅广泛尝试解决这个问题,而且还在 Whosebug 和其他网站上进行了大量研究以了解如何解决此问题。需要说明的是,我学习 WPF 大约 3 个月左右,来自 WinForms,目前仍处于学习阶段。
这是我的问题。
我有一个要添加到 TreeView 控件的 TreeViewItems。这些 TreeView 项使用创建自定义外观的 Style,我正在尝试实现它,这几乎是整个应用程序的外观。样式使用显式 Setter.Value 反对模板 属性 来创建 TreeView 项目的自定义外观。它有自己的自定义扩展器箭头,绑定到 TreeViewItem header 的 TextBlock header,当然还有一个 ContentPresenter 和一个 ItemsPresenter。还有一个连接到 TreeViewItem 的 IsExpanded 值的触发器,以便在展开或折叠 TreeViewItem 时可以显示或隐藏 ItemsPresenter。除折叠和展开部分外,一切正常。当然,ItemsPresenter 会像它应该的那样隐藏和显示,但是当 IsExpanded 为 false 时,TreeViewItem 本身实际上并没有折叠它的高度。为了说明我的意思,这里有 2 张图片来说明发生了什么。我在样式模板中的网格周围添加了一个绿色边框,以表明单个 TreeViewItem 本身在折叠时没有缩小其 "height"。
展开
Pic of expanded tree view item
崩溃
Pic of collapsed tree view item
如您所见,绿色边框或树视图项目本身在折叠时的高度与展开时的高度相同。这是用于创建 TreeViewItem 自身自定义样式的 XAML。
TreeViewItem 样式XAML代码:
<Style x:Key="TreeViewItemStyle" TargetType="TreeViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeViewItem">
<Border x:Name="MyBorder" BorderThickness="1" BorderBrush="LawnGreen">
<Grid HorizontalAlignment="Left" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="25"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ui:TreeViewItemExpander x:Name="TreeViewItemExpander" Grid.Row="0" Grid.Column="0" IsPointingDown="{TemplateBinding IsExpanded}"/>
<!--This represents the text for the tree view item itself-->
<TextBlock Text="{TemplateBinding Header}" Grid.Row ="0" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Center" Foreground="White"/>
<ContentPresenter x:Name="ContentPresenter" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<ItemsPresenter x:Name="ItemsPresenter" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" Visibility="Hidden"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="ItemsPresenter" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
下面这段代码是我使用样式的方式
<TreeView Style="{StaticResource TreeViewStyle}" Width="200" Margin="419,337,19,328">
<controls:CustomTreeViewItem Header="Folder 1" Style="{StaticResource TreeViewItemStyle}">
<Button Content="Item 1" HorizontalAlignment="Left" VerticalAlignment="Top" Height="20"/>
<Button Content="Item 2" HorizontalAlignment="Left" VerticalAlignment="Top" Height="20"/>
</controls:CustomTreeViewItem>
</TreeView>
感谢任何人可以提供的任何输入或帮助。我希望我已经足够清楚了。
我明白了。我所做的只是在 IsExpanded 触发器中添加一个 setter 以设置 ItemsPresenter 所在的网格行的 属性。我所做的只是将行的高度设置为 0,这实际上隐藏了项目。这是上面代码中应用了更改的触发器本身的代码。
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="Items" Property="Visibility" Value="Visible"/>
<Setter TargetName="ItemsRow" Property="Height" Value="0"/>
</Trigger>
</ControlTemplate.Triggers>
如果其他人有更好的解决方案,我很感兴趣。弄清楚这一点后,我又考虑将行的高度设置为 0 以提供更好的效果,但没有成功。我发现 StoryBoard 是可冻结的,并且在 Style 或 ControlTemplate 内部时被冻结。这意味着如果您希望它具有动画效果,那么项目折叠的动画必须通过代码隐藏实现,或者在每个 TreeViewItem 上单独实现?我相信有更好的方法。如果我知道如何做到这一点,我会更新这个post供大家参考。请随时添加到此 post 更好的解决方案!!