GridSplitter Autosize

问题描述 投票:1回答:1

我对GridSplitter有问题

简单的示例代码:

<Grid x:Name="MainGrid">
    <Grid.RowDefinitions>
        <RowDefinition Height="100"></RowDefinition>
        <RowDefinition Height="2"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <Grid x:Name="TopGrid" Grid.Row="0"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Red"/>
    <GridSplitter ResizeDirection="Rows" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="2" Background="Black" />
    <Grid x:Name="BottomGrid" Grid.Row="2" HorizontalAlignment="Stretch"  Background="Aquamarine" VerticalAlignment="Stretch"/>
</Grid>

[这将创建两个由GridSplitter垂直分隔的网格。

我想要实现的是,GridSplitter自动与Grid的内容对齐。例如,如果我在底部的Grid中有一个可折叠的元素,那么我希望在折叠该元素时顶部的Grid变得更大。如果我将其展开,则顶部Grid应该变小。

我该如何做?稍后我将有4 Grids和3 GridSplitter´s,因此解决方案也应与多个GridSplitter´s一起使用。

[编辑]:

我的xaml:

 <Grid x:Name="MainGrid">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="100">
            <RowDefinition.MinHeight>
                <MultiBinding Converter="{StaticResource ResourceKey=MultiValueConverter}">
                    <Binding ElementName="dgStapelliste" Path="ActualHeight"></Binding>
                </MultiBinding>
            </RowDefinition.MinHeight>
        </RowDefinition>
        <RowDefinition Height="1"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition >           
    </Grid.RowDefinitions>

    <Grid Grid.Row="0" Grid.Column="0" x:Name="Test">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="200"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <WPF:DataGrid GridHeaderContent="{Binding StapelListe.HeaderText}" SelectedItem="{Binding StapelListe.SelectedItem}" Grid.Row="0" Grid.Column="0" x:Name="dgStapelliste" HorizontalAlignment="Stretch" ItemsSource="{Binding StapelListe, Mode=OneWay,  UpdateSourceTrigger=PropertyChanged}"/>
        <WPF:DataGrid GridHeaderContent="{Binding EinzelListe.HeaderText}" Grid.Row="0" Grid.Column="1" x:Name="dgEinzelliste" HorizontalAlignment="Stretch"  ItemsSource="{Binding EinzelListe, Mode=OneWay}"/>

        <GridSplitter Grid.Column="0" Width="1" VerticalAlignment="Stretch" Background="Black" />
    </Grid>

    <Grid Grid.Row="2" Grid.Column="0" Grid.RowSpan="2">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="200"/>
        </Grid.ColumnDefinitions>

        <WPF:DataGrid  GridHeaderContent="{Binding Anforderungsliste.HeaderText}" Grid.Column="0" x:Name="dgAnforderungsliste" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Anforderungsliste, Mode=OneWay}"/>

        <GridSplitter Grid.Column="0" Width="1" VerticalAlignment="Stretch" Background="Black" />
    </Grid>
    <GridSplitter Grid.Column="0" Grid.Row="1" Height="1" ResizeDirection="Rows"  VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Black" x:Name="testSplitter" />
</Grid>
c# wpf xaml grid gridsplitter
1个回答
3
投票
您可以使用MultiBinding实现您想要的。

为每个RowDefinition设置一个MinHeight,将其绑定到其内容ActualHeight就像这样:

<RowDefinition Height="100"> <RowDefinition.MinHeight> <MultiBinding Converter="{StaticResource ResourceKey=CalcAll}"> <Binding ElementName="firstElementInThisRow" Path="ActualHeight"></Binding> <Binding ElementName="secondElementInThisRow" Path="ActualHeight"></Binding> <Binding ElementName="thirdElementInThisRow" Path="ActualHeight"></Binding> <Binding ElementName="fourthElementInThisRow" Path="ActualHeight"></Binding> </MultiBinding> </RowDefinition.MinHeight> </RowDefinition>

您的转换器可能看起来像:

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { double result = 0.0; foreach (object item in values) { result += System.Convert.ToDouble(item); } return result; } public object[] ConvertBack(object values, Type[] targetType, object parameter, CultureInfo culture) { return null; }

每次扩展控件时,它的ActualHeight都会更改,并且Binding会更新->父级RowDefinition的MinHeight会更改。

但是,如果将VerticalAlignment控件设置为Stretch,则不能将其设置为1,因为这将不会通过扩展更改ActualHeight。

EDIT:由于我现在唯一想到的属性是DesiredSize.Height属性,因此不能使用Binding(如果DesiredSize.Height值更改,则绑定不会更新)。但是也许您可以使用double类型的属性(我们将其称为MinHeightRowOne),该属性会在设置器中引发PropertyChanged事件,并绑定到第一行MinHeight(每行一个属性):

public double _minHeightRowOne; public double MinHeightRowOne { get { return _minHeightRowOne; } set { _minHeightRowOne = value; OnPropertyChanged("MinHeightRowOne"); } } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string name) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(name)); } }

<RowDefinition Height="100" MinHeight="{Binding Path=MinHeightRowOne}"/>

现在将此事件处理程序添加到第一行中每个控件的SizeChanged-Event(每行一个处理程序:]

private List<KeyValuePair<string,double>> oldVals = new List<KeyValuePair<string,double>>(); private void ElementInRowOneSizeChanged(object sender, SizeChangedEventArgs e) { FrameworkElement elem = (FrameworkElement)sender; MinHeightRowOne -= oldVals.Find(kvp => kvp.Key == elem.Name).Value; elem.Measure(new Size(int.MaxValue, int.MaxValue)); MinHeightRowOne += elem.DesiredSize.Height; oldVals.Remove(oldVals.Find(kvp => kvp.Key == elem.Name)); oldVals.Add(new KeyValuePair<string, double>(elem.Name, elem.DesiredSize.Height)); }

因此,每当控件的大小更改时,行的MinHeight都会更新(应该包括展开或折叠的项目。)>]

请注意,每个控件必须具有唯一的名称才能进行此工作。

© www.soinside.com 2019 - 2024. All rights reserved.