簡體   English   中英

GridSplitter 自動調整大小

[英]GridSplitter Autosize

我在使用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應該會變小。

我該怎么做呢? 稍后我將有 4 個帶有 3 個GridSplitterGrids ......所以該解決方案也應該與多個GridSplitter一起使用。

[編輯]:

我的 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>

您可以使用 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,則不能設置一個,因為這樣 ActualHeight 不會因擴展而改變。

編輯:由於我現在能想到的唯一屬性是 DesiredSize.Height 屬性,您不能使用 Binding(如果 DesiredSize.Height 值更改,則綁定不會更新)。 但也許您可以使用 double 類型的屬性(我們稱之為 MinHeightRowOne),它會在它的 setter 中引發 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}"/>

現在將此 EventHandler 添加到第一行中每個控件的 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 都會更新。

請注意,每個控件都必須有一個唯一的名稱才能使其工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM