2

3列の単純なグリッドがあります(そのうちの1つにはグリッドスプリッターが含まれています)。グリッドのサイズを変更すると、左側の列が最小幅に達すると、何もしない代わりに、右側の列の幅が大きくなります。誰かが私がこれを止めるのを手伝ってもらえますか?

グリッド自体もサイズ変更されるため、右側の列の最大幅を設定できません。

問題を示すサンプルコードを次に示します。サイズ変更中に、マウスを赤い領域に移動します。

XAML:

<Grid DockPanel.Dock="Top" Height="200">
    <Grid.ColumnDefinitions>
        <ColumnDefinition MinWidth="200" Width="*" />
        <ColumnDefinition Width="3" />
        <ColumnDefinition MinWidth="120" Width="240" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Rectangle Fill="Red" Grid.Row="0" Grid.Column="0" />
    <DockPanel LastChildFill="True" Grid.Row="0" Grid.Column="2" >
        <Rectangle DockPanel.Dock="Right" Width="20" Fill="Blue" />
        <Rectangle Fill="Green" />
    </DockPanel>
    <GridSplitter Background="LightGray" Grid.Row="0" Grid.Column="1" Height="Auto" Width="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</Grid>
4

3 に答える 3

3

私はこれが少し遅いことを知っています、しかし私はちょうどこの問題に遭遇します、そしてここに私の解決策があります。残念ながら、それは十分に一般的ではなく、2列のグリッドに対してのみ機能しますが、おそらくさらに適応させることができます。しかし、それは記述された問題と私自身の問題を解決するので、ここに行きます:

解決策はハックまたは回避策で構成されていますが、それを呼び出したいと思います。左と右の両方の列にMinWidthを宣言する代わりに、最初の列にMinWidthとMaxWidthを宣言します。これは、GridSplitterが定義された場所の右側に移動しないことを意味します。ここまでは順調ですね。

次の問題は、サイズ変更可能なコンテナ(私の場合はウィンドウ)がある場合、これでは不十分であるということです。これは、2番目の列に十分なスペースがある場合でも、左側の列を必要なだけ拡大できないことを意味します。幸いなことに、解決策があります。グリッドのActualWidthにバインドし、加算コンバーターを使用します。コンバーターパラメータは、グリッド幅から減算する必要があるため、実際には右側の列に必要な最小幅であり、明らかに負の値になります。SubtractConvertorを使用することもできますが、それはあなた次第です。

xamlとコードは次のとおりです。

<Grid Background="{DynamicResource MainBackground}" x:Name="MainGrid" >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="200" MinWidth="100" MaxWidth="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=Grid}, Converter={Converters:AdditionConverter}, ConverterParameter=-250}" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <GridSplitter  Width="3" VerticalAlignment="Stretch" Grid.Column="0"/>
    <!-- your content goes here -->
</Grid>

およびコンバーター:

[ValueConversion(typeof(double), typeof(double))]
public class AdditionConverter : MarkupExtension, IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        double dParameter;
        if (targetType != typeof(double) ||
            !double.TryParse((string)parameter, NumberStyles.Any, CultureInfo.InvariantCulture, out dParameter))
        {
            throw new InvalidOperationException("Value and parameter passed must be of type double");
        }
        var dValue = (double)value;
        return dValue + dParameter;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }

    #endregion

    #region Overrides of MarkupExtension

    /// <summary>
    /// When implemented in a derived class, returns an object that is set as the value of the target property for this markup extension. 
    /// </summary>
    /// <returns>
    /// The object value to set on the property where the extension is applied. 
    /// </returns>
    /// <param name="serviceProvider">Object that can provide services for the markup extension.
    ///                 </param>
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }

    #endregion
}

これがお役に立てば幸いです。

ミハイ・ドレボット

于 2011-06-09T18:46:42.730 に答える
2

このアプローチはハックですが、目的の効果を得るために使用できます。Window.SizeChangedイベントにイベントハンドラーを配置して、最初のcolumndefのmaxWidthを設定してみてください。例えば:

private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
     int borderBuffer = 9;
     //              AppWindow Size    Splitter Width     Far Column Min  FudgeFactor                
     Col0.MaxWidth = e.NewSize.Width - Col1.Width.Value - Col2.MinWidth - borderBuffer;
}

この方法を使用して、グリッドの一番上の行にあるサードパーティのコントロールが、幅が「自動」に設定されている列の最小/最大幅をgridSplitterが無視した場合に、望ましくない折り返しが発生しないようにする必要がありました。場合によっては、borderBufferを調整する必要があります。私の場合のborderBufferは、ジオメトリ/列/境界線の幅に基づいて完全に意味をなさなかった-それは私のレイアウトで機能した魔法の数でした。

誰かがよりクリーンな解決策を思い付くことができれば、代わりにそれを使用したいと思います。このソリューションは、VB6にコントロールのサイズを変更させようとする苦痛を思い出させます。しかし、今のところ、予期しないラッピングが原因でグリッドの一番上の行にアイテムが非表示になるのを上回っています。

于 2010-05-26T07:50:21.453 に答える
1

*columndefinitionのinをtoAutoおよび240toに変更することで、この望ましくない動作を停止させました*

于 2010-04-12T22:40:47.773 に答える