Horizo​​ntalAlignment =“Stretch”在TreeViewItem

时间:2016-02-22 15:05:19

标签: c# .net wpf xaml

以下是一个不起作用的示例:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication2"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <TreeView HorizontalAlignment="Stretch">
        <TreeViewItem Header="Stuff" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
            <Grid HorizontalAlignment="Stretch">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Label Grid.Column="0">Some random text</Label>
                <TextBox Grid.Column="1"></TextBox>

            </Grid>
        </TreeViewItem>
    </TreeView>
</Window>

我希望文本框拉伸到窗口的宽度,但是你得到这个:

what it looks like

what it looks like at runtime

文字框会在您输入时展开,这不是我想要的。

我现在想的是,可以将第二列宽度的绑定设置为TreeViewItem的宽度,但我不知道该怎么做。

我已经尝试将网格放在各种面板中,但这也不起作用。我还在文本框本身设置了HorizontalAlignmentHorizontalContentAlignmentStretch,但这也不起作用。

这是Grid控制的一些限制吗?将文本框单独放在树视图中会使其按照我的意愿进行扩展,但我需要将标签放在它旁边,如果有多个字段,如果所有文本框都对齐,它看起来会好多了。

更新

使用不同的ControlTemplate允许标题拉伸但内容仍然无法拉伸。

<TreeView HorizontalAlignment="Stretch">
        <TreeViewItem Style="{DynamicResource StretchableTreeViewItemTemplate}" HorizontalAlignment="Stretch" Header="Stuff">
            <Grid HorizontalAlignment="Stretch">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Label Grid.Column="0">Some random text</Label>
                <TextBox Grid.Column="1" HorizontalAlignment="Stretch"></TextBox>
            </Grid>
        </TreeViewItem>
    </TreeView>



<Style x:Key="StretchableTreeViewItemTemplate" TargetType="TreeViewItem"
   BasedOn="{StaticResource {x:Type TreeViewItem}}">
        <Setter Property="HorizontalContentAlignment"
      Value="Center" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="TreeViewItem">
                    <StackPanel>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"
                            MinWidth="19" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition />
                            </Grid.RowDefinitions>
                            <!--
                         Note that the following do not work, but I believe the top 2 should?!
                         <ToggleButton IsChecked="{TemplateBinding IsExpanded}" ClickMode="Press" Name="Expander">
                         <ToggleButton IsChecked="{TemplateBinding Property=IsExpanded}" ClickMode="Press" Name="Expander">
                         <ToggleButton IsChecked="{TemplateBinding Path=IsExpanded}" ClickMode="Press" Name="Expander">
                    -->
                            <ToggleButton IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
                      ClickMode="Press"
                      Name="Expander">
                                <ToggleButton.Style>
                                    <Style TargetType="ToggleButton">
                                        <Setter Property="UIElement.Focusable"
                      Value="false" />
                                        <Setter Property="FrameworkElement.Width"
                      Value="16" />
                                        <Setter Property="FrameworkElement.Height"
                      Value="16" />
                                        <Setter Property="Control.Template">
                                            <Setter.Value>
                                                <ControlTemplate TargetType="ToggleButton">
                                                    <Border Padding="5,5,5,5"
                            Background="#00FFFFFF"
                            Width="16"
                            Height="16">
                                                        <Path Fill="#00FFFFFF"
                            Stroke="#FF989898"
                            Name="ExpandPath">
                                                            <Path.Data>
                                                                <PathGeometry Figures="M0,0L0,6L6,0z" />
                                                            </Path.Data>
                                                            <Path.RenderTransform>
                                                                <RotateTransform Angle="135"
                                           CenterX="3"
                                           CenterY="3" />
                                                            </Path.RenderTransform>
                                                        </Path>
                                                    </Border>
                                                    <ControlTemplate.Triggers>
                                                        <Trigger Property="UIElement.IsMouseOver"
                               Value="True">
                                                            <Setter TargetName="ExpandPath"
                                Property="Shape.Stroke"
                                Value="#FF1BBBFA" />
                                                            <Setter TargetName="ExpandPath"
                                Property="Shape.Fill"
                                Value="#00FFFFFF" />
                                                        </Trigger>
                                                        <Trigger Property="ToggleButton.IsChecked"
                               Value="True">
                                                            <Setter TargetName="ExpandPath"
                                Property="UIElement.RenderTransform">
                                                                <Setter.Value>
                                                                    <RotateTransform Angle="180"
                                             CenterX="3"
                                             CenterY="3" />
                                                                </Setter.Value>
                                                            </Setter>
                                                            <Setter TargetName="ExpandPath"
                                Property="Shape.Fill"
                                Value="#FF595959" />
                                                            <Setter TargetName="ExpandPath"
                                Property="Shape.Stroke"
                                Value="#FF262626" />
                                                        </Trigger>
                                                    </ControlTemplate.Triggers>
                                                </ControlTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </ToggleButton.Style>
                            </ToggleButton>
                            <Border x:Name="Bd"
                HorizontalAlignment="Stretch"
                BorderThickness="{TemplateBinding Border.BorderThickness}"
                BorderBrush="{TemplateBinding Border.BorderBrush}"
                Padding="{TemplateBinding Control.Padding}"
                Background="{TemplateBinding Panel.Background}"
                SnapsToDevicePixels="True"
                Grid.Column="1">
                                <ContentPresenter x:Name="PART_Header"
                            Content="{TemplateBinding HeaderedContentControl.Header}"
                            ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}"
                            ContentStringFormat="{TemplateBinding HeaderedItemsControl.HeaderStringFormat}"
                            ContentTemplateSelector="{TemplateBinding HeaderedItemsControl.HeaderTemplateSelector}"
                            ContentSource="Header"
                            HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
                            SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                            </Border>
                            <ItemsPresenter x:Name="ItemsHost"
                        Grid.Column="1"
                        Grid.Row="1" />
                        </Grid>
                    </StackPanel>
                    <ControlTemplate.Triggers>
                        <Trigger Property="TreeViewItem.IsExpanded"
               Value="False">
                            <Setter TargetName="ItemsHost"
                Property="UIElement.Visibility"
                Value="Collapsed" />
                        </Trigger>
                        <Trigger Property="ItemsControl.HasItems"
               Value="False">
                            <Setter TargetName="Expander"
                Property="UIElement.Visibility"
                Value="Hidden" />
                        </Trigger>
                        <Trigger Property="TreeViewItem.IsSelected"
               Value="True">
                            <Setter TargetName="Bd"
                Property="Panel.Background"
                Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
                            <Setter Property="TextElement.Foreground"
                Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                        </Trigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="TreeViewItem.IsSelected"
                     Value="True" />
                                <Condition Property="Selector.IsSelectionActive"
                     Value="False" />
                            </MultiTrigger.Conditions>
                            <Setter TargetName="Bd"
                Property="Panel.Background"
                Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
                            <Setter Property="TextElement.Foreground"
                Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
                        </MultiTrigger>
                        <Trigger Property="UIElement.IsEnabled"
               Value="False">
                            <Setter Property="TextElement.Foreground"
                Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

结果:

with control template edited

尝试使用Pikoh的解决方案:

<local:StretchingTreeView HorizontalAlignment="Stretch">
    <local:StretchingTreeViewItem HorizontalAlignment="Stretch" Header="Stuff">
        <Grid HorizontalAlignment="Stretch">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Label Grid.Column="0">Some random text</Label>
            <TextBox Grid.Column="1" HorizontalAlignment="Stretch"></TextBox>
        </Grid>
    </local:StretchingTreeViewItem>
</local:StretchingTreeView>

results with Pikoh's solution

4 个答案:

答案 0 :(得分:2)

由于Microsoft在创建WPF时做出了奇怪的设计决策,因此如果不替换控件模板,树项就无法延伸。

请参阅http://leecampbell.blogspot.com/2009/01/horizontal-stretch-on-treeviewitems.html

所需的风格是:

<Style TargetType="TreeViewItem"
       BasedOn="{StaticResource {x:Type TreeViewItem}}">
  <Setter Property="HorizontalContentAlignment"
          Value="Center" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="TreeViewItem">
        <StackPanel>
          <Grid>
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="Auto"
                                MinWidth="19" />
              <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
              <RowDefinition Height="Auto" />
              <RowDefinition />
            </Grid.RowDefinitions>
            <!--
                             Note that the following do not work, but I believe the top 2 should?!
                             <ToggleButton IsChecked="{TemplateBinding IsExpanded}" ClickMode="Press" Name="Expander">
                             <ToggleButton IsChecked="{TemplateBinding Property=IsExpanded}" ClickMode="Press" Name="Expander">
                             <ToggleButton IsChecked="{TemplateBinding Path=IsExpanded}" ClickMode="Press" Name="Expander">
                        -->
            <ToggleButton IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
                          ClickMode="Press"
                          Name="Expander">
              <ToggleButton.Style>
                <Style TargetType="ToggleButton">
                  <Setter Property="UIElement.Focusable"
                          Value="false" />
                  <Setter Property="FrameworkElement.Width"
                          Value="16" />
                  <Setter Property="FrameworkElement.Height"
                          Value="16" />
                  <Setter Property="Control.Template">
                    <Setter.Value>
                      <ControlTemplate TargetType="ToggleButton">
                        <Border Padding="5,5,5,5"
                                Background="#00FFFFFF"
                                Width="16"
                                Height="16">
                          <Path Fill="#00FFFFFF"
                                Stroke="#FF989898"
                                Name="ExpandPath">
                            <Path.Data>
                              <PathGeometry Figures="M0,0L0,6L6,0z" />
                            </Path.Data>
                            <Path.RenderTransform>
                              <RotateTransform Angle="135"
                                               CenterX="3"
                                               CenterY="3" />
                            </Path.RenderTransform>
                          </Path>
                        </Border>
                        <ControlTemplate.Triggers>
                          <Trigger Property="UIElement.IsMouseOver"
                                   Value="True">
                            <Setter TargetName="ExpandPath"
                                    Property="Shape.Stroke"
                                    Value="#FF1BBBFA" />
                            <Setter TargetName="ExpandPath"
                                    Property="Shape.Fill"
                                    Value="#00FFFFFF" />
                          </Trigger>
                          <Trigger Property="ToggleButton.IsChecked"
                                   Value="True">
                            <Setter TargetName="ExpandPath"
                                    Property="UIElement.RenderTransform">
                              <Setter.Value>
                                <RotateTransform Angle="180"
                                                 CenterX="3"
                                                 CenterY="3" />
                              </Setter.Value>
                            </Setter>
                            <Setter TargetName="ExpandPath"
                                    Property="Shape.Fill"
                                    Value="#FF595959" />
                            <Setter TargetName="ExpandPath"
                                    Property="Shape.Stroke"
                                    Value="#FF262626" />
                          </Trigger>
                        </ControlTemplate.Triggers>
                      </ControlTemplate>
                    </Setter.Value>
                  </Setter>
                </Style>
              </ToggleButton.Style>
            </ToggleButton>
            <Border x:Name="Bd"
                    HorizontalAlignment="Stretch"
                    BorderThickness="{TemplateBinding Border.BorderThickness}"
                    BorderBrush="{TemplateBinding Border.BorderBrush}"
                    Padding="{TemplateBinding Control.Padding}"
                    Background="{TemplateBinding Panel.Background}"
                    SnapsToDevicePixels="True"
                    Grid.Column="1">
              <ContentPresenter x:Name="PART_Header"
                                Content="{TemplateBinding HeaderedContentControl.Header}"
                                ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}"
                                ContentStringFormat="{TemplateBinding HeaderedItemsControl.HeaderStringFormat}"
                                ContentTemplateSelector="{TemplateBinding HeaderedItemsControl.HeaderTemplateSelector}"
                                ContentSource="Header"
                                HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
                                SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
            </Border>
            <ItemsPresenter x:Name="ItemsHost"
                            Grid.Column="1"
                            Grid.Row="1" />
          </Grid>
        </StackPanel>
        <ControlTemplate.Triggers>
          <Trigger Property="TreeViewItem.IsExpanded"
                   Value="False">
            <Setter TargetName="ItemsHost"
                    Property="UIElement.Visibility"
                    Value="Collapsed" />
          </Trigger>
          <Trigger Property="ItemsControl.HasItems"
                   Value="False">
            <Setter TargetName="Expander"
                    Property="UIElement.Visibility"
                    Value="Hidden" />
          </Trigger>
          <Trigger Property="TreeViewItem.IsSelected"
                   Value="True">
            <Setter TargetName="Bd"
                    Property="Panel.Background"
                    Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
            <Setter Property="TextElement.Foreground"
                    Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
          </Trigger>
          <MultiTrigger>
            <MultiTrigger.Conditions>
              <Condition Property="TreeViewItem.IsSelected"
                         Value="True" />
              <Condition Property="Selector.IsSelectionActive"
                         Value="False" />
            </MultiTrigger.Conditions>
            <Setter TargetName="Bd"
                    Property="Panel.Background"
                    Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
            <Setter Property="TextElement.Foreground"
                    Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
          </MultiTrigger>
          <Trigger Property="UIElement.IsEnabled"
                   Value="False">
            <Setter Property="TextElement.Foreground"
                    Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

答案 1 :(得分:2)

描述了问题的核心(以及解决它的方法)here

ControlTemplate 的默认 TreeViewItem 使用 3 列 x 2 行的网格,定义为内容不能水平拉伸。作者还给出了一种修改样式,即改变网格使内容可以拉伸。

请注意,修改后的样式将 HorizontalContentAlignmentTreeViewItem 设置为 Center,并且 ControlTemplate 使用此属性来对齐内容。

要达到所需的效果,请在修改后的样式中将 HorizontalContentAlignment 设置为 Stretch,或者在 {{ 1}}(或特定的 TreeView)。

缺少 TreeViewItems 部分会导致 TreeViewItem 恢复使用默认的 BasedOn="{StaticResource {x:Type TreeViewItem}}",以及不可拉伸的网格。

ControlTemplate

<Style TargetType="TreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}"> <Setter Property="HorizontalContentAlignment" Value="Stretch"/> </Style> 中,效果将通过使用 HierarchicalDataTemplate 属性来实现。

@pikoh 从 ItemContainerStyleTreeView 派生的方法通过修改代码中的网格来实现相同的目的。

完整示例:

TreeViewItem

Screen capture

答案 2 :(得分:1)

尝试这样的事情:

<TextBox Grid.Column="1" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type Grid}}, Mode=OneWay}"></TextBox>

修改

好的,我找到了一个解决方案Here。它基本上创建了一个继承Treeview的新类:

class StretchingTreeView : TreeView
{
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new StretchingTreeViewItem();
    }

    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return item is StretchingTreeViewItem;
    }
}

class StretchingTreeViewItem : TreeViewItem
{
    public StretchingTreeViewItem()
    {
        this.Loaded += new RoutedEventHandler(StretchingTreeViewItem_Loaded);
    }

    private void StretchingTreeViewItem_Loaded(object sender, RoutedEventArgs e)
    {
        // The purpose of this code is to stretch the Header Content all the way accross the TreeView. 
        if (this.VisualChildrenCount > 0)
        {
            Grid grid = this.GetVisualChild(0) as Grid;
            if (grid != null && grid.ColumnDefinitions.Count == 3)
            {
                // Remove the middle column which is set to Auto and let it get replaced with the 
                // last column that is set to Star.
                grid.ColumnDefinitions.RemoveAt(1);
            }
        }
    }

    protected override DependencyObject GetContainerForItemOverride()
    {
        return new StretchingTreeViewItem();
    }

    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return item is StretchingTreeViewItem;
    }
}

使用示例:

<Window x:Class="WpfApplication2.Window2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication2"
    Title="Window2" Height="300" Width="300">
<Grid>

    <local:StretchingTreeView HorizontalAlignment="Stretch" >

        <local:StretchingTreeViewItem Header="Stuff" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" >
            <Grid HorizontalAlignment="Stretch" >
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Label Grid.Column="0">Some random text</Label>
                <TextBox Grid.Column="1" ></TextBox>

            </Grid>
        </local:StretchingTreeViewItem>
    </local:StretchingTreeView>
</Grid>

答案 3 :(得分:0)

似乎是Grid's HorizontalAlignment问题。我已经尝试过了。Net Framework 4这一切都运行正常。似乎在4.5中,即使您将HorizontalAlignment指定为Stretch,它实际上也不会拉伸它。所以你可以像下面那样进行绑定:

<Grid HorizontalAlignment="Stretch" 
      Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}},Path=ActualWidth,Mode=OneTime}"
              >

因为您可以在运行时看到TreeViewItem具有预期的宽度但Grid不会。