C# 如何在树视图中包裹包裹儿童?
我有一个树视图,里面有一位家长和两个孩子。孩子们依次由一个包裹自己的孩子组成(“一”、“二”、“三”等)。当父窗口不够大,无法容纳这些最后的元素时,我如何才能将它们包装起来 这是我的密码:C# 如何在树视图中包裹包裹儿童?,c#,wpf,xaml,C#,Wpf,Xaml,我有一个树视图,里面有一位家长和两个孩子。孩子们依次由一个包裹自己的孩子组成(“一”、“二”、“三”等)。当父窗口不够大,无法容纳这些最后的元素时,我如何才能将它们包装起来 这是我的密码: <TreeView ScrollViewer.HorizontalScrollBarVisibility="Disabled"> <TreeViewItem Header="Parent" IsExpanded="True" > <ItemsContr
<TreeView ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<TreeViewItem Header="Parent" IsExpanded="True" >
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Items>
<TextBlock Text="One" />
<TextBlock Text="Two" />
<TextBlock Text="Three" />
<TextBlock Text="Four" />
<TextBlock Text="Five" />
<TextBlock Text="Six" />
<TextBlock Text="Seven" />
<TextBlock Text="Eight" />
<TextBlock Text="Nine" />
<TextBlock Text="Ten" />
</ItemsControl.Items>
</ItemsControl>
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Items>
<TextBlock Text="One" />
<TextBlock Text="Two" />
<TextBlock Text="Three" />
<TextBlock Text="Four" />
<TextBlock Text="Five" />
<TextBlock Text="Six" />
<TextBlock Text="Seven" />
<TextBlock Text="Eight" />
<TextBlock Text="Nine" />
<TextBlock Text="Ten" />
</ItemsControl.Items>
</ItemsControl>
</TreeViewItem>
</TreeView>
以下是它目前生产的产品:
请测试此解决方法。您必须将
SizeChanged=“TreeView\u SizeChanged”
添加到TreeView
项中
private void TreeView_SizeChanged(object sender, SizeChangedEventArgs e)
{
var treeView = (TreeView) sender;
foreach (TreeViewItem treeViewItem in treeView.Items)
{
foreach (ItemsControl ic in treeViewItem.Items)
{
Point relativeLocation = ic.TranslatePoint(new Point(0, 0), treeView);
var wpMaxWidth = treeView.ActualWidth - relativeLocation.X;
WrapPanel itemsWp = GetVisualChild<WrapPanel>(ic);
itemsWp.MaxWidth = wpMaxWidth;
}
}
}
private static T GetVisualChild<T>(DependencyObject parent) where T : Visual
{
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual) VisualTreeHelper.GetChild(parent, i);
var child = v as T;
return child ?? GetVisualChild<T>(v);
}
return null;
}
IMultiValueConverter
Convert
方法实现:
...
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var wp = values[0] as WrapPanel;
var tv = values[1] as TreeView;
if (wp == null || tv == null)
return 0d;
Point relativeLocation = wp.TranslatePoint(new Point(0, 0), tv);
var wpMaxWidth = tv.ActualWidth - relativeLocation.X;
return wpMaxWidth;
}
...
注意:您必须在容器大小更改后刷新
绑定。请测试此解决方法。您必须将SizeChanged=“TreeView\u SizeChanged”
添加到TreeView
项中
private void TreeView_SizeChanged(object sender, SizeChangedEventArgs e)
{
var treeView = (TreeView) sender;
foreach (TreeViewItem treeViewItem in treeView.Items)
{
foreach (ItemsControl ic in treeViewItem.Items)
{
Point relativeLocation = ic.TranslatePoint(new Point(0, 0), treeView);
var wpMaxWidth = treeView.ActualWidth - relativeLocation.X;
WrapPanel itemsWp = GetVisualChild<WrapPanel>(ic);
itemsWp.MaxWidth = wpMaxWidth;
}
}
}
private static T GetVisualChild<T>(DependencyObject parent) where T : Visual
{
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual) VisualTreeHelper.GetChild(parent, i);
var child = v as T;
return child ?? GetVisualChild<T>(v);
}
return null;
}
IMultiValueConverter
Convert
方法实现:
...
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var wp = values[0] as WrapPanel;
var tv = values[1] as TreeView;
if (wp == null || tv == null)
return 0d;
Point relativeLocation = wp.TranslatePoint(new Point(0, 0), tv);
var wpMaxWidth = tv.ActualWidth - relativeLocation.X;
return wpMaxWidth;
}
...
注意:您必须在容器大小更改后刷新绑定。请测试此解决方法。您必须将SizeChanged=“TreeView\u SizeChanged”
添加到TreeView
项中
private void TreeView_SizeChanged(object sender, SizeChangedEventArgs e)
{
var treeView = (TreeView) sender;
foreach (TreeViewItem treeViewItem in treeView.Items)
{
foreach (ItemsControl ic in treeViewItem.Items)
{
Point relativeLocation = ic.TranslatePoint(new Point(0, 0), treeView);
var wpMaxWidth = treeView.ActualWidth - relativeLocation.X;
WrapPanel itemsWp = GetVisualChild<WrapPanel>(ic);
itemsWp.MaxWidth = wpMaxWidth;
}
}
}
private static T GetVisualChild<T>(DependencyObject parent) where T : Visual
{
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual) VisualTreeHelper.GetChild(parent, i);
var child = v as T;
return child ?? GetVisualChild<T>(v);
}
return null;
}
IMultiValueConverter
Convert
方法实现:
...
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var wp = values[0] as WrapPanel;
var tv = values[1] as TreeView;
if (wp == null || tv == null)
return 0d;
Point relativeLocation = wp.TranslatePoint(new Point(0, 0), tv);
var wpMaxWidth = tv.ActualWidth - relativeLocation.X;
return wpMaxWidth;
}
...
注意:您必须在容器大小更改后刷新绑定。请测试此解决方法。您必须将SizeChanged=“TreeView\u SizeChanged”
添加到TreeView
项中
private void TreeView_SizeChanged(object sender, SizeChangedEventArgs e)
{
var treeView = (TreeView) sender;
foreach (TreeViewItem treeViewItem in treeView.Items)
{
foreach (ItemsControl ic in treeViewItem.Items)
{
Point relativeLocation = ic.TranslatePoint(new Point(0, 0), treeView);
var wpMaxWidth = treeView.ActualWidth - relativeLocation.X;
WrapPanel itemsWp = GetVisualChild<WrapPanel>(ic);
itemsWp.MaxWidth = wpMaxWidth;
}
}
}
private static T GetVisualChild<T>(DependencyObject parent) where T : Visual
{
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual) VisualTreeHelper.GetChild(parent, i);
var child = v as T;
return child ?? GetVisualChild<T>(v);
}
return null;
}
IMultiValueConverter
Convert
方法实现:
...
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var wp = values[0] as WrapPanel;
var tv = values[1] as TreeView;
if (wp == null || tv == null)
return 0d;
Point relativeLocation = wp.TranslatePoint(new Point(0, 0), tv);
var wpMaxWidth = tv.ActualWidth - relativeLocation.X;
return wpMaxWidth;
}
...
注意:您必须在容器大小更改后刷新绑定。我修改了解决方案2,以考虑垂直滚动条宽度和垂直滚动条可见性。还添加了对treeview宽度更改的重新计算。
XAML:
我修改了解决方案2,将垂直滚动条宽度和垂直滚动条可见性考虑在内。还添加了对treeview宽度更改的重新计算。
XAML:
我修改了解决方案2,将垂直滚动条宽度和垂直滚动条可见性考虑在内。还添加了对treeview宽度更改的重新计算。
XAML:
我修改了解决方案2,将垂直滚动条宽度和垂直滚动条可见性考虑在内。还添加了对treeview宽度更改的重新计算。
XAML:
我问这个问题已经有几年了,在此期间我学到了很多关于WPF布局的知识。事实上,这可以仅在XAML中完成,我现在将为将来遇到此问题的任何人发布。关键是模板出TreeViewItem,并检查它用于填充树的每个级别的XAML
简而言之,树视图的每一层都由一个包含两行三列的网格组成。第一行是TreeViewItem头,第二行是子项
还有三列。第0列表示扩展器图标,第1列表示标题内容,第2列表示所有剩余空间。孩子们都坐在ContentPresenter中,它占据了第二行的第1列和第2列。此网格的列定义显示了一些有趣的内容:
<ColumnDefinition MinWidth="19" Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
默认情况下,扩展器图标为16x16,但列0的MinWidth设置为19像素。因此,除非您更改扩展器图标,否则19像素将是ContentPresenter开头的缩进。因此,您只需将每个子项控件绑定到其TreeViewItem的宽度,并在右侧为其提供19像素的填充(或扩展器图标的任何宽度):
<ItemsControl Width="{Binding RelativeSource={RelativeSource AncestorType= {x:Type TreeViewItem}, AncestorLevel=1}, Path=ActualWidth}" Padding="0 0 19 0">
结果是像素完美包裹:
(请注意,此解决方案还将适应出现和消失的滚动条,并在滚动条出现和消失时相应地重新排列包装项)。我问这个问题已经有几年了,在此期间我学到了很多关于WPF布局的知识。事实上,这可以仅在XAML中完成,我现在将为将来遇到此问题的任何人发布。关键是模板出TreeViewItem,并检查它用于填充树的每个级别的XAML
简而言之,树视图的每一层都由一个包含两行三列的网格组成。第一行是TreeViewItem头,第二行是子项
还有三列。第0列表示扩展器图标,第1列表示标题内容,第2列表示所有剩余空间。孩子们都坐在ContentPresenter中,它占据了第二行的第1列和第2列。此网格的列定义显示了一些有趣的内容:
<ColumnDefinition MinWidth="19" Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
默认情况下,扩展器图标为16x16,但列0的MinWidth设置为19像素。因此,除非您更改扩展器图标,否则19像素将是ContentPresenter开头的缩进。因此,您只需将每个子项控件绑定到其TreeViewItem的宽度,并在右侧为其提供19像素的填充(或扩展器图标的任何宽度):
<ItemsControl Width="{Binding RelativeSource={RelativeSource AncestorType= {x:Type TreeViewItem}, AncestorLevel=1}, Path=ActualWidth}" Padding="0 0 19 0">
结果是像素完美包裹:
(请注意,此解决方案还将适应出现和消失的滚动条,并在滚动条出现和消失时相应地重新安排包装项)。我问这个问题已经好几年了,我学到了一个很好的方法