如何在TreeView中获取TreeViewItem的可用(可见)宽度

Gre*_*ban 1 wpf treeview width treeviewitem

我有一个包含3列Grid的网格,TreeViewItem其中HierarchicalDataTemplate包含以下定义:

<Grid>    
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition Width="1*" />
    <ColumnDefinition Width="Auto" />
...
Run Code Online (Sandbox Code Playgroud)

我想设置网格的宽度,以便它完全占用TreeViewItem内部的所有可用空间TreeView.因此,网格的第三列应该在内部对齐TreeView.

如何获得网格宽度的正确值?

我知道,对于ListBox ItemTemplate,我可以通过将其绑定到以下来设置宽度ScrollContentPresenter:

Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ScrollContentPresenter, AncestorLevel=1}, Path=ActualWidth}"
Run Code Online (Sandbox Code Playgroud)

这个技巧不起作用TreeView,因为孩子们的可用空间比根树视图项目少.

有任何想法吗?

Gre*_*ban 6

在使用它几个小时后,我找到了一个使用Multibinding两个转换器的工作解决方案.

一,HierarchicalDataTemplateXAML中的定义:

<HierarchicalDataTemplate>
<Grid>
   <Grid.Width>
      <MultiBinding Converter="{StaticResource SumConverterInstance}">
          <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=ScrollContentPresenter, AncestorLevel=1}" Path="ActualWidth" />
          <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=TreeViewItem, AncestorLevel=1}" Converter="{StaticResource ParentCountConverterInstance}" />
      </MultiBinding>
    </Grid.Width>   
   .... (content of the template) ....
</Grid>
</HierarchicalDataTemplate>
Run Code Online (Sandbox Code Playgroud)

在multibinding所述第一结合得到的宽度ScrollContentPresenterTreeView,这是的总可见宽度TreeView.第二个绑定使用TreeViewItem作为参数的转换器调用,并计算TreeViewItem在到达根项之前有多少父项.使用这两个输入,我们使用SumConverterInstance Multibinding来计算给定的可用宽度TreeViewItem.

以下是XAML中定义的转换器实例:

  <my:SumConverter x:Key="SumConverterInstance" />
  <my:ParentCountConverter x:Key="ParentCountConverterInstance" />
Run Code Online (Sandbox Code Playgroud)

以及两个转换器的代码:

// combine the width of the TreeView control and the number of parent items to compute available width
public class SumConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double totalWidth = (double)values[0];
        double parentCount = (double)values[1];
        return totalWidth - parentCount * 20.0;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

// count the number of TreeViewItems before reaching ScrollContentPresenter
public class ParentCountConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        int parentCount = 1;
        DependencyObject o = VisualTreeHelper.GetParent(value as DependencyObject);
        while (o != null && o.GetType().FullName != "System.Windows.Controls.ScrollContentPresenter")
        {
            if (o.GetType().FullName == "System.Windows.Controls.TreeViewItem")
                parentCount += 1;
            o = VisualTreeHelper.GetParent(o);
        }
        return parentCount;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是正确的看法:

alt text http://img249.imageshack.us/img249/6889/atts2.png