WPF Expander.Header 水平拉伸

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31161591/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:14:15  来源:igfitidea点击:

WPF Expander.Header horizontal stretch

c#wpfxamlexpander

提问by scher

I have an Expander in Wpf. In the header I have Label on left aligned and want to have a button on the right site. I use the following XAML:

我在 Wpf 中有一个扩展器。在标题中,我将 Label 左对齐并希望在右侧站点上有一个按钮。我使用以下 XAML:

<Expander HorizontalAlignment="Stretch" IsExpanded="True">
    <Expander.Header >
        <Grid HorizontalAlignment="Stretch" Background="Aqua" Margin="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <Label Grid.Column="0" Content="Label on the left site"/>
            <Button Grid.Column="1" Content="Button on the right"/>
         </Grid>
    </Expander.Header>
    <Label Content="Some Content"/>
</Expander>

But that does not work. The button in the header is aligned to the left, next to the label. Can anyone explain me how to do it right?

但这不起作用。标题中的按钮向左对齐,在标签旁边。谁能解释我如何正确地做到这一点?

回答by Sinatr

Expanderheader content presenter has horizontal alignment set to Left.

Expander标题内容演示者的水平对齐方式设置为Left

You can change it to Stretchusing OneWayToSourcebinding of HorizontalAlignment(which is by default Stretchfor Grid) like this:

您可以将其更改为Stretch使用OneWayToSource绑定HorizontalAlignment(默认StretchGrid),如下所示:

<Expander>
    <Expander.Header>
        <Grid Background="Yellow">
            <TextBlock Text="Header"
                       HorizontalAlignment="{Binding HorizontalAlignment, RelativeSource={RelativeSource AncestorType=ContentPresenter}, Mode=OneWayToSource}" />
        </Grid>
    </Expander.Header>
</Expander>

P.S.: it took me more than it should to understand the solution of accepted answer, so I decide to save the time for future readers.

PS:我花了比理解已接受答案的解决方案更多的时间,所以我决定为未来的读者节省时间。

回答by Dean Lunz

I was able to get content stretching in the header to work using the xaml provided below. Basically I data bind the grids HorizontailAlignment to the content presenter ancestor. Unfortunatley the solution provided by scher (data binding to ActualWidth) can cause ui elements to be displayed wider then there container resulting in controls being partially cut off.) Bolu's link to the article "Stretching Content in an Expander Header" uses code behind where as this example uses pure xaml.

我能够使用下面提供的 xaml 使标题中的内容拉伸工作。基本上我的数据将网格 Horizo​​ntailAlignment 绑定到内容展示器祖先。不幸的是,scher 提供的解决方案(数据绑定到 ActualWidth)会导致 ui 元素显示得比容器更宽,从而导致控件被部分切断。) Bolu 指向文章“在扩展器标题中拉伸内容”的链接使用了 where 后面的代码此示例使用纯 xaml。

<ItemsControl x:Name="ItemGroups" Grid.Column="2" Grid.Row="0"   ItemsSource="{Binding Model.ItemGroups}" ScrollViewer.VerticalScrollBarVisibility="Auto" >
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Expander Margin="4,0"   Header="{Binding}">
                        <Expander.HeaderTemplate>
                            <DataTemplate>
                                <Grid  HorizontalAlignment="{Binding Path=HorizontalAlignment, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentPresenter}}, Mode=OneWayToSource}" >
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition   />
                                        <ColumnDefinition  Width="Auto"/>
                                        <ColumnDefinition  Width="64"/>
                                    </Grid.ColumnDefinitions>

                                    <TextBox Grid.Column="0"  Text="{Binding Name, Mode=TwoWay}" />
                                    <TextBlock Grid.Column="1" Text="{Binding TotalCostString}" Margin="4,0"/>
                                    <Button Grid.Column="2" Command="{Binding DataContext.RemoveItemGroup, ElementName=ItemGroups, Mode=OneWay}" CommandParameter="{Binding}" Content="Remove"/>
                                </Grid>         
                            </DataTemplate>
                        </Expander.HeaderTemplate>
                        <Expander.Content>
                            <TextBlock Text="{Binding Summary}"></TextBlock>
                        </Expander.Content>
                    </Expander>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

回答by scher

I took one of the solutions linked by Bolu. This is the result:

我采用了 Bolu 链接的解决方案之一。这是结果:

    <Expander HorizontalAlignment="Stretch" IsExpanded="True">
        <Expander.Header >
            <!-- Width-Binding is needed, to fill the whole header horizontally-->
            <Grid HorizontalAlignment="Stretch" Background="Aqua" Margin="0" Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Expander}}, Path=ActualWidth}">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <Label Grid.Column="0" Content="Label on the left site"/>
                <!-- Margin is needed, to bring the Button into the view -->
                <Button Grid.Column="1" Content="Button on the right" Margin="0,0,40,0"/>
            </Grid>
        </Expander.Header>
        <Label Content="Some Content"/>
    </Expander>

回答by dee

*Heck: right padding to e.g. 100000: Padding="2 2 100000 2"

*见鬼:正确填充到例如 100000: Padding="2 2 100000 2"

<Expander Name="Name" ExpandDirection="Down">
    <Expander.Header>
        <TextBlock Text="Expander..." Margin="0 5" Padding="2 2 100000 2" />
    </Expander.Header>
</Expander>

回答by mamuesstack

If you don't want to change the Expander Header look at all you could also use Behaviors (System.Windows.Interactivity) that modifies the HorizontalAlignment when the Header is being loaded

如果您不想更改 Expander Header 查看所有内容,您还可以使用 Behaviors (System.Windows.Interactivity) 在加载 Header 时修改 Horizo​​ntalAlignment

internal class StretchingExpanderHeaderBehavior : Behavior<Expander>
{
    protected override void OnAttached()
    {
        AssociatedObject.Loaded += StretchHeader;
    }

    private void StretchHeader(object sender, RoutedEventArgs e)
    {
        DependencyObject header = AssociatedObject.Header as DependencyObject;
        if (header != null)
        {
            ContentPresenter contentPresenter = VisualTreeHelper.GetParent(header) as ContentPresenter;
            if (contentPresenter != null)
            {
                contentPresenter.HorizontalAlignment = HorizontalAlignment.Stretch;
            }
        }
    }
}

This can be attached to the Expander

这可以附加到扩展器

<Expander>
    <Expander.Header>
        <DockPanel HorizontalAlignment="Stretch">
            <Button DockPanel.Dock="Right" Content="Button on the right" />
            <Label Content="Label on the left site"/>
        </DockPanel>
    </Expander.Header>

    <Border BorderBrush="LightGray" BorderThickness="1">
        <ItemsPresenter />
    </Border>

    <iy:Interaction.Behaviors>
        <bhv:StretchingExpanderHeaderBehavior />
    </iy:Interaction.Behaviors>

</Expander>