5

次の XAML コードを使用して、GridSplitter で区切られた 2 つの列を持つグリッドがあります。

<Grid>
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="100" MinWidth="20" />
    <ColumnDefinition Width="10" />
    <ColumnDefinition Width="*" MinWidth="100" />
    </Grid.ColumnDefinitions>

    <Rectangle Fill="Blue" />
    <GridSplitter Grid.Column="1" Background="LightGray" HorizontalAlignment="Stretch" />
    <Rectangle Fill="Yellow" Grid.Column="2" />
</Grid>

問題: 右側の列の MinWidth が無視される

  • ページの読み込み時に最初の列の幅を「100px」にする必要があるため、 * サイズにすることはできません。
  • 最初の列に MaxWidth を設定したくない

*以前に対処されたことは知っていますが、列サイズを*に設定するか、最初の列にmaxWidthを設定することを常に提案しています...私はそれを望んでいません。


解決策を見つけましたが、醜いです! :p、誰もが私が望むものを達成するためのよりクリーンな方法を持っています...コードレス(可能であれば)?

private void Grid_SizeChanged(object sender, SizeChangedEventArgs e)
{
   var g = (Grid)sender;

   Double maxW = e.NewSize.Width - g.ColumnDefinitions[2].MinWidth - g.ColumnDefinitions[1].ActualWidth;
   g.ColumnDefinitions[0].MaxWidth = maxW;
}
4

2 に答える 2

6

基本的な問題は、グリッド スプリッターが左の列の幅のみを調整することによって機能し、右の列が残りのスペースに合わせて星形のサイズになると想定することです。

つまり、解決しようとしている問題は、実際には「右の列が小さくなりすぎないように、左の列の最大幅を制限するにはどうすればよいですか?」ということです。これは基本的にコードサンプルが行っていることです。

XAML で実装できる、より移植性の高いソリューションが必要な場合は、グリッドに適用できるSilverlight動作を作成します (以下を参照)。これは親グリッドのSizeChangedイベントにアタッチされ、コード スニペットとほぼ同じように動作しますが、Blend でドラッグ アンド ドロップしたり、XAML でアタッチしたりできる動作です。

これは、例としてまとめたサンプル動作です (独自のコードに基づいています)。

MinWidthSplitterBehavior.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;

namespace GridSplitterMinWidth
{
    public class MinWidthSplitterBehavior : Behavior<Grid>
    {
        public Grid ParentGrid { get; set; }

        protected override void OnAttached()
        {
            base.OnAttached();
            ParentGrid = this.AssociatedObject as Grid;
            ParentGrid.SizeChanged += parent_SizeChanged;
        }

        void parent_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (ParentGrid.ColumnDefinitions.Count == 3)
            {
                Double maxW = e.NewSize.Width - ParentGrid.ColumnDefinitions[2].MinWidth -
                              ParentGrid.ColumnDefinitions[1].ActualWidth;
                ParentGrid.ColumnDefinitions[0].MaxWidth = maxW;
            }
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            if (ParentGrid != null)
            {
                ParentGrid.SizeChanged -= parent_SizeChanged;
            }
        }
    }
}

次のように使用します。

<UserControl x:Class="GridSplitterMinWidthApp.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:GridSplitterMinWidth="clr-namespace:GridSplitterMinWidth"
    xmlns:interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:Controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100" MinWidth="20" />
                <ColumnDefinition Width="10" />
                <ColumnDefinition Width="*" MinWidth="100" />
            </Grid.ColumnDefinitions>
            <interactivity:Interaction.Behaviors>
                <GridSplitterMinWidth:MinWidthSplitterBehavior/>
            </interactivity:Interaction.Behaviors>
            <Rectangle Fill="Blue" />
            <Controls:GridSplitter Grid.Column="1" Background="LightGray" HorizontalAlignment="Stretch">
            </Controls:GridSplitter>
            <Rectangle Fill="Yellow" Grid.Column="2" />
        </Grid>
    </Grid>
</UserControl>
于 2012-07-01T08:03:33.813 に答える