如何拉伸 TreeViewItem 宽度以填充父项?
Posted
技术标签:
【中文标题】如何拉伸 TreeViewItem 宽度以填充父项?【英文标题】:How to stretch TreeViewItem width to fill parent? 【发布时间】:2018-04-25 19:37:58 【问题描述】:我有一个 WPF TreeView,我想像它的父级一样将 TreeViewItem 拉伸到整个空间。
<TreeView Name="treeFamilies" AllowDrop="True" >
<TreeView.Resources>
<HierarchicalDataTemplate DataType="x:Type local:MyNode" ItemsSource="Binding Members">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Binding Name" Background="LightGray"/>
<TextBlock Text=" [" Foreground="Blue" Background="LightGray"/>
<TextBlock Text="Binding Members.Count" Foreground="Blue" Background="LightGray"/>
<TextBlock Text="]" Foreground="Blue" Background="LightGray" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style TargetType="x:Type TreeViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
看来我错误地使用了 ItemContainer 样式 <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
。我现在的树看起来像这张照片:
我希望拉伸灰色背景以填充树视图控件的整个末端。 我怎样才能做到这一点?
【问题讨论】:
看看here 不确定,但我认为使用StackPanel
会给您带来一些问题。我经常无法按照我想要的方式使用它。您还可以考虑将树项的宽度、RelativeSource 绑定到父元素。
@Il Vic 您的链接非常有用。
【参考方案1】:
Form Il Vic 的评论,this msdn blog 显示了一种 hack-like 方法来删除 TreeViewItem
的最后一列。
如果博客关闭,我会在此处复制我的工作代码。加载TreeViewItem
后,我从网格中删除第三个ColumnDefinition
,并将第二个ColumnDefinition
宽度设置为*
;
public class StretchingTreeViewItem : TreeViewItem
public StretchingTreeViewItem()
this.Loaded += new RoutedEventHandler(StretchingTreeViewItem_Loaded);
private void StretchingTreeViewItem_Loaded(object sender, RoutedEventArgs e)
if (this.VisualChildrenCount > 0)
Grid grid = this.GetVisualChild(0) as Grid;
if (grid != null && grid.ColumnDefinitions.Count == 3)
grid.ColumnDefinitions.RemoveAt(2);
grid.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Star);
protected override DependencyObject GetContainerForItemOverride()
return new StretchingTreeViewItem();
protected override bool IsItemItsOwnContainerOverride(object item)
return item is StretchingTreeViewItem;
然后我覆盖TreeView
以获取自定义项。
public class StretchingTreeView : TreeView
protected override DependencyObject GetContainerForItemOverride()
return new StretchingTreeViewItem();
protected override bool IsItemItsOwnContainerOverride(object item)
return item is StretchingTreeViewItem;
【讨论】:
【参考方案2】:您必须覆盖树视图 itemcontainerstyle 的模板,这对微软来说有点奇怪,但您必须将整个模板写成新的。所以不会有扩展器或类似的东西,但是使用此代码,您的树视图项目将延伸到整个父级。我将 IsExpanded 设置为 true,因此您的孩子仍会显示。
<TreeView Margin="10"
ItemsSource="Binding ChainedCommandVMs">
<TreeView.ItemContainerStyle>
<Style TargetType="x:Type TreeViewItem">
<Setter Property="IsExpanded"
Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeViewItem">
<StackPanel>
<ContentPresenter ContentSource="Header" />
<ItemsPresenter Name="ItemsHost" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TreeView.ItemContainerStyle>...
如果您想保持正常行为,例如查看本教程的展开按钮,它将帮助您重写整个模板: https://wpf.2000things.com/2017/09/23/1218-stretching-items-in-treeview-across-entire-control/
【讨论】:
【参考方案3】:我想出了一个非常简单的方法来实现这个(虽然也不完美):绑定到树视图的ActualWidth
属性
<TreeView x:Name="ListUI">
<TreeView.Resources>
<DataTemplate>
<Grid HorizontalAlignment="Stretch"
Width="Binding ActualWidth,
ElementName=ListUI,
Converter=StaticResource MinusFortyFiveConverter">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Left Side" />
<!-- Will gap in the middle -->
<TextBlock Grid.Column="2" Text="Right Side" />
</Grid>
</DataTemplate>
</TreeView.Resources>
</TreeView>
您可能需要一个值转换器,将数字减少 10 左右,否则会太宽,请根据您的皮肤需要进行调整。我对默认皮肤的初始测试是负 45 是一个很好的起点。
public class MinusFortyFiveConverter : IValueConverter
/// <inheritdoc/>
public object Convert(
object value, Type targetType, object parameter, CultureInfo culture)
return (double)value - 45;
/// <inheritdoc/>
public object ConvertBack(
object value, Type targetType, object parameter, CultureInfo culture)
throw new NotSupportedException("Cannot convert back");
【讨论】:
以上是关于如何拉伸 TreeViewItem 宽度以填充父项?的主要内容,如果未能解决你的问题,请参考以下文章