7

グリッドを含む WPF ページがあります。

3列あります。行 0 には GridView が含まれていますHeight="*"。行 1 には GridSplitter が含まれていHeight="auto"ます。行 2 には、詳細フォームが含まれていHeight="2*"ます。

これが問題です-詳細フォームの表示を切り替えるボタンがあります。そして、それはうまく機能します。行 2 のフォームを非表示にするだけで、行 0 のグリッドを拡張してスペースを埋めることはありません。私が望むのは、ボタンが行 0 の GridView を切り替えてすべてのスペースを占有し、元の場所に切り替えることです。

明らかに、行内のフォームの可視性をいじっても、私が望む結果は得られません。

しかし、私は何をいじる必要がありますか?

4

4 に答える 4

7

次の XAML レイアウトがあるとします。

  <Grid Name="MyGrid">
      <Grid.RowDefinitions>
          <RowDefinition />
          <RowDefinition Height="Auto" />
          <RowDefinition />
      </Grid.RowDefinitions>
      <MyControl1 ... Grid.Row="0" />
      <GridSplitter Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Stretch" ShowsPreview="True" Height="5" />
      <MyControl2 ... Grid.Row="2" />
  </Grid>

Height="0"次に、次のコード ( XAMLでの設定と同等) を使用して、2 番目のコントロールを非表示にする (スプリッターを折りたたむ) ことができます。

  MyGrid.RowDefinitions[2].Height = new GridLength(0);

そして、次のコードで展開します ( Height="1*"RowDefinition のデフォルトである XAML での設定と同等です)。

  MyGrid.RowDefinitions[2].Height = new GridLength(1, GridUnitType.Star);

これは、ユーザーがスプリッターを動かしたときにスプリッターが隠れて行うことです。

于 2015-12-09T11:12:55.860 に答える
4

自分のアプリケーションでこれを処理するには、添付の依存関係プロパティを導入する必要がありました。

<Grid c:GridSplitterController.Watch="{Binding ElementName=GS_DetailsView}">
    <Grid.RowDefinitions>
        <RowDefinition Height="1*" />
        <RowDefinition Height="200" />
    </Grid.RowDefinitions>

    <SomeControl Grid.Row="0" />

    <GridSplitter x:Name="GS_DetailsView"
                  Height="4"
                  Grid.Row="1"
                  VerticalAlignment="Top"
                  HorizontalAlignment="Stretch"
                  ResizeBehavior="PreviousAndCurrent"
                  ResizeDirection="Rows"
                  Visibility="{Binding ShowDetails,
                                       Converter={StaticResource boolvis}}" />

    <OtherControl Grid.Row="1"
                  Margin="0,4,0,0"
                  Visibility="{Binding ShowDetails,
                                       Converter={StaticResource boolvis}}" />
</Grid>

最初に に適切な添付プロパティを定義しますDependencyObject

public static GridSplitter GetWatch(DependencyObject obj)
{
    return (GridSplitter)obj.GetValue(WatchProperty);
}

public static void SetWatch(DependencyObject obj, GridSplitter value)
{
    obj.SetValue(WatchProperty, value);
}

public static readonly DependencyProperty WatchProperty =
    DependencyProperty.RegisterAttached(
        "Watch",
        typeof(GridSplitter),
        typeof(DependencyObject),
        new UIPropertyMetadata(null, OnWatchChanged));

次に、次をリッスンしIsVisibleChangedます。

private static void OnWatchChanged(DependencyObject obj,
    DependencyPropertyChangedEventArgs e)
{
    if (obj == null) return;
    if (obj is Grid)
    {
        var grid = obj as Grid;
        var gs = e.NewValue as GridSplitter;
        if (gs != null)
        {
            gs.IsVisibleChanged += (_sender, _e) =>
                {
                    UpdateGrid(
                        grid,
                        (GridSplitter)_sender,
                        (bool)_e.NewValue,
                        (bool)_e.OldValue);
                };
        }
    }
}

これらの変更を監視したら、監視してGridLengthいる行または列の値を保存または復元する必要があります (簡潔にするために、行のみを含めています)。

// Given: static Dictionary<DependencyObject, GridLength> oldValues;
private static void UpdateGrid(Grid grid, GridSplitter gridSplitter, bool newValue, bool oldValue)
{
    if (newValue)
    {
        // We're visible again
        switch (gridSplitter.ResizeDirection)
        {
        case GridResizeDirection.Columns:
            break;
        case GridResizeDirection.Rows:
            int ridx = (int)gridSplitter.GetValue(Grid.RowProperty);
            var prev = grid.RowDefinitions.ElementAt(GetPrevious(gridSplitter, ridx));
            var curr = grid.RowDefinitions.ElementAt(GetNext(gridSplitter, ridx));
            if (oldValues.ContainsKey(prev) && oldValues.ContainsKey(curr))
            {
                prev.Height = oldValues[prev];
                curr.Height = oldValues[curr];
            }

            break;
        }
    }
    else
    {
        // We're being hidden
        switch (gridSplitter.ResizeDirection)
        {
        case GridResizeDirection.Columns:
            break;
        case GridResizeDirection.Rows:
            int ridx = (int)gridSplitter.GetValue(Grid.RowProperty);
            var prev = grid.RowDefinitions.ElementAt(GetPrevious(gridSplitter, ridx));
            var curr = grid.RowDefinitions.ElementAt(GetNext(gridSplitter, ridx));
            switch (gridSplitter.ResizeBehavior)
            {
                // Naively assumes only one type of collapsing!
                case GridResizeBehavior.PreviousAndCurrent:
                    oldValues[prev] = prev.Height;
                    prev.Height = new GridLength(1.0, GridUnitType.Star);

                    oldValues[curr] = curr.Height;
                    curr.Height = new GridLength(0.0);
                    break;
            }
            break;
        }
    }
}

残っているのは、GetPreviousandの適切な実装だけGetNextです。

private static int GetPrevious(GridSplitter gridSplitter, int index)
{
    switch (gridSplitter.ResizeBehavior)
    {
        case GridResizeBehavior.PreviousAndNext:
        case GridResizeBehavior.PreviousAndCurrent:
            return index - 1;
        case GridResizeBehavior.CurrentAndNext:
            return index;
        case GridResizeBehavior.BasedOnAlignment:
        default:
            throw new NotSupportedException();
    }
}

private static int GetNext(GridSplitter gridSplitter, int index)
{
    switch (gridSplitter.ResizeBehavior)
    {
        case GridResizeBehavior.PreviousAndCurrent:
            return index;
        case GridResizeBehavior.PreviousAndNext:
        case GridResizeBehavior.CurrentAndNext:
            return index + 1;
        case GridResizeBehavior.BasedOnAlignment:
        default:
            throw new NotSupportedException();
    }
}
于 2012-09-18T18:53:36.380 に答える
3

このGridExpanderコントロールは、探しているジョブに役立つフォーム GridSpliter を継承します。WPF での私自身の使用法に適合させたオリジナルの Silverlight バージョンを作成したShemeshに感謝します。GridSplitter を使用しようとするほぼすべての場所でこの機能が必要になるので、非常に便利です。

于 2012-10-07T03:32:15.320 に答える