简体   繁体   English

如何在代码隐藏中获取WPF扩展器切换按钮的宽度

[英]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? 如何访问切换按钮代码的宽度,以便可以相应地更改columndefinitions?

在此处输入图片说明

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. 人们可能会尝试通过查看控件模板并进行补偿来自己找到该切换按钮的宽度,但这是不可靠的,因为该模板可以在.NET版本(如果我没记错的话,以及操作系统)之间进行更改,并且无论如何都难以实现。

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 "*". 您可以通过共享 2-4列的列宽并将第1列的宽度设置为“ *”来实现。 Doing this initially will yield undesired results however, because the Expander Header template has no way to set the HorizontalContentAlignment. 但是,最初这样做会产生不希望的结果,因为Expander Header模板无法设置Horizo​​ntalContentAlignment。

第一次尝试

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. 让我们将扩展器的BorderThickness设置为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. 更好-(空格消失了),但是.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. 我在合理的时间内找不到该间隙的来源,因此我只是将扩展器的“边距”设置为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?) 根据内容的不同,可能需要在扩展器内部对此进行补偿,并调出隐藏的CSS hack记忆(假设XAML会更好,不是吗?)

End Result: 最终结果:

最后

XAML: 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. 结论:这可行,但是如果发现扩展器的控制模板太乱了,您可能要考虑对其进行覆盖。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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