如何在 TreeView 中包装 TextBlock 内容? [英] How to wrap TextBlock content in TreeView?
问题描述
我有 TreeView
,它使用数据模板显示一些数据.这是 XAML:
I have TreeView
, which displays some data using data templates. Here's XAML:
<TreeView Grid.Row="0" ItemsSource="{Binding Railways}" x:Name="tvDatawareObjects"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<!-- other templates here... -->
<HierarchicalDataTemplate DataType="{x:Type viewModels:ProjectViewModel}" ItemsSource="{Binding Phases}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Model.Code}" FontWeight="DemiBold" />
<TextBlock Text="{Binding Model.Title}" TextWrapping="Wrap" Foreground="Gray" Grid.Row="1" />
</Grid>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type viewModels:CollectionViewModel}" ItemsSource="{Binding Items}">
<TextBlock Text="{Binding CollectionName}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
<TextBlock Text="{Binding Model.Title}" TextWrapping="Wrap" Foreground="Gray" Grid.Row="1"/>
的文本换行不起作用.我做错了什么?
Text wrapping for <TextBlock Text="{Binding Model.Title}" TextWrapping="Wrap" Foreground="Gray" Grid.Row="1" />
doesn't work. What am I doing wrong?
推荐答案
我做到了.:)
根据 Dan 的回答中提供的链接,原因在于默认的 TreeViewItemTemplate.
Accordind to the link, provided in the Dan's answer, the reason is lying in the default TreeViewItemTemplate.
不幸的是,对 TreeView.ActualWidth
的简单绑定无济于事.这是因为根据定义,每个项目的宽度小于 TreeView.ActualWidth
- 项目渲染时有一些水平偏移,具体取决于它们的级别.
Unfortunately, simple binding to TreeView.ActualWidth
can't help. This is because width of each item is less than TreeView.ActualWidth
by definition - items are rendered with some horizontal offset, depending on their level.
因此,为了解决这个问题,我需要像这样计算项目的宽度:
Hence, to solve the problem, I need to calculate width of item like this:
width = actual_width_of_tree_view - relative_horizontal_offset_of_item
更准确地说,我需要ScrollViewer.ViewportWidth
,因为TreeViewContent 可能会垂直滚动,并且TreeView
的可见区域将小于TreeView.实际宽度
在这种情况下.
To be more precise, I need ScrollViewer.ViewportWidth
, so as TreeViewContent might be scrolled vertically, and visible area of TreeView
will be less than TreeView.ActualWidth
in this case.
这是附加的财产:
public static Double GetProjectTitleWidth(DependencyObject obj)
{
return (Double)obj.GetValue(ProjectTitleWidthProperty);
}
public static void SetProjectTitleWidth(DependencyObject obj, Double value)
{
obj.SetValue(ProjectTitleWidthProperty, value);
}
public static readonly DependencyProperty ProjectTitleWidthProperty = DependencyProperty.RegisterAttached(
"ProjectTitleWidth",
typeof(Double),
typeof(DatawareSearchView),
new UIPropertyMetadata(0.0, ProjectTitleWidthChanged));
private static void ProjectTitleWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var targetElement = d as FrameworkElement;
if (targetElement != null)
{
var bindingExpr = targetElement.GetBindingExpression(ProjectTitleWidthProperty);
var sourceElement = bindingExpr.DataItem as FrameworkElement;
if (sourceElement != null)
{
// calculating relative offset
var leftTop = targetElement.TranslatePoint(new Point(0.0, 0.0), sourceElement);
// trying to find ScrollViewer
var border = VisualTreeHelper.GetChild(sourceElement, 0);
if (border != null)
{
var scrollViewer = VisualTreeHelper.GetChild(border, 0) as ScrollViewer;
if (scrollViewer != null)
{
// setting width of target element
targetElement.Width = scrollViewer.ViewportWidth - leftTop.X;
}
}
}
}
}
...和标记:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Model.Code}" FontWeight="DemiBold" />
<TextBlock Text="{Binding Model.Title}" TextWrapping="Wrap" Foreground="Gray" x:Name="tbTitle" Grid.Row="1"
localviews:DatawareSearchView.ProjectTitleWidth="{Binding RelativeSource={RelativeSource AncestorType=TreeView}, Path=ActualWidth}"/>
</Grid>
当然,提供的解决方案不是通用的 - 它假设 TreeView 具有 Border
和 ScrollViewer
.
Of course, provided solution isn't universal - it assumes, that TreeView has Border
and ScrollViewer
.
这篇关于如何在 TreeView 中包装 TextBlock 内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!