简体   繁体   中英

How to get the width of wpf expander togglebutton in codebehind

I want to build a customcontrol where expandable rows are added to grid. In order to match the columns of the expandable row, I added another grid as expander header and content. However, the columns are slightly tilted to the right (see picture). I think it is because of the header size?

How do I access the width of the togglebutton code, so I can change the columndefinitions accordingly?

在此处输入图片说明

Thanks!

There are a few ways to approach this.

One would be trying to find the width of that togglebutton yourself by looking at the control template and compensating - but this is unreliable as the template can change across .NET versions (and operating systems if I recall correctly) and is messy to implement anyway.

The second way is trying to programatically find the width and compensate that way, but that still requires digging into the control template (see issues above)

The third is to let the layout engine figure things out for you. You can do this by sharing the column width on columns 2-4, and setting the width of column 1 to "*". Doing this initially will yield undesired results however, because the Expander Header template has no way to set the HorizontalContentAlignment.

第一次尝试

With a little of the above mentioned risk, you can fix that by digging around in the template via codebehind, as described here But its still not perfect yet.

更紧密

Looks like there is a border or margin somewhere. Lets set the BorderThickness of the expander to 0.

令人沮丧

UGH! Better - (the whitespace is gone), but there is still a gap between our grid (red with black border) and the green in .NET 4.5. I could not find the source of this gap in a reasonable amount of time, so I just set the Margin of the expander to 0,0,-1,0. This might need to be compensated for inside the expander depending on content, and brings up suppressed memories of CSS hacks (XAML was suppose to be better, wasn't it?)

End Result:

最后

XAML:

<Window x:Class="Sandbox.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="800" SnapsToDevicePixels="True">
<Window.Resources>
    <DataTemplate x:Key="StretchedHeaderTemplate">
        <Border HorizontalAlignment="Stretch" Loaded="Border_Loaded">
            <ContentPresenter Content="{TemplateBinding Content}"/>
        </Border>
    </DataTemplate>
</Window.Resources>
<Grid Grid.IsSharedSizeScope="True" Margin="15">
    <Grid.ColumnDefinitions>
        <ColumnDefinition x:Name="MainLeft"/>
        <ColumnDefinition x:Name="MainRight"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Grid Grid.Column="0" Background="AliceBlue">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="100" SharedSizeGroup="Col2"/>
            <ColumnDefinition Width="100" SharedSizeGroup="Col3"/>
            <ColumnDefinition Width="100" SharedSizeGroup="Col4"/>
        </Grid.ColumnDefinitions>
        <Border Grid.Column="0" BorderBrush="Black" BorderThickness="1">
            <TextBlock>Col1</TextBlock>
        </Border>
        <Border Grid.Column="1" BorderBrush="Black" BorderThickness="1">
            <TextBlock>Col2</TextBlock>
        </Border>
        <Border Grid.Column="2" BorderBrush="Black" BorderThickness="1">
            <TextBlock>Col3</TextBlock>
        </Border>
        <Border Grid.Column="3" BorderBrush="Black" BorderThickness="1">
            <TextBlock>Col4</TextBlock>
        </Border>
    </Grid>
    <Grid Grid.Column="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="0" HorizontalAlignment="Center">January</TextBlock>
        <TextBlock Grid.Column="1" HorizontalAlignment="Center">February</TextBlock>
        <TextBlock Grid.Column="2" HorizontalAlignment="Center">March</TextBlock>
    </Grid>
    <StackPanel Grid.Column="0" Grid.Row="1">
        <Expander HeaderTemplate="{StaticResource StretchedHeaderTemplate}" Background="LightGreen" BorderThickness="0" Margin="0,0,-1,0">
            <Expander.Header>
                <Grid HorizontalAlignment="Stretch" Background="LightCoral">
                    <Grid Grid.Column="0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition SharedSizeGroup="Col2"/>
                            <ColumnDefinition SharedSizeGroup="Col3"/>
                            <ColumnDefinition SharedSizeGroup="Col4"/>
                        </Grid.ColumnDefinitions>
                        <Border Grid.Column="0" BorderBrush="Black" BorderThickness="1">
                            <TextBlock>Record1</TextBlock>
                        </Border>
                        <Border Grid.Column="1" BorderBrush="Black" BorderThickness="1">
                            <TextBlock>02.05.2016</TextBlock>
                        </Border>
                        <Border Grid.Column="2" BorderBrush="Black" BorderThickness="1">
                            <TextBlock>05.05.2017</TextBlock>
                        </Border>
                        <Border Grid.Column="3" BorderBrush="Black" BorderThickness="1">
                            <TextBlock>340</TextBlock>
                        </Border>
                    </Grid>
                </Grid>
            </Expander.Header>
        </Expander>
    </StackPanel>
</Grid>

Code Behind:

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Border_Loaded(object sender, RoutedEventArgs e)
    {
        Border root = (Border)sender;
        ContentPresenter presenter = (ContentPresenter)root.TemplatedParent;
        presenter.HorizontalAlignment = HorizontalAlignment.Stretch;
    }
}

Conclusion: This works, but you might want to consider overriding the control template for the Expander if you find any of it too messy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM