2010-04-12 15 views
2

J'ai une grille simple avec 3 colonnes (dont une contient un séparateur de réseau). Lorsque vous redimensionnez la grille et que la colonne de gauche atteint sa largeur minimale, au lieu de ne rien faire, elle augmente la largeur de la colonne de droite. Quelqu'un pourrait-il m'aider à arrêter cela?Comportement de séparateur de réseau indésirable WPF

Je ne peux pas définir la largeur maximale de la colonne de droite, car la grille elle-même redimensionne également.

Voici un exemple de code qui montre le problème. Alors que le redimensionnement, déplacez la souris sur la zone rouge:

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> 

Répondre

2

Cette approche est un hack mais peut être utilisée pour l'effet désiré. Essayez de placer un gestionnaire d'événements sur l'événement Window.SizeChanged pour définir la largeur maximale du premier columndef. Par exemple:

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; 
} 

I nécessaire d'utiliser cette méthode pour empêcher un contrôle d'un tiers dans la rangée supérieure de la grille d'avoir un certain enveloppement indésirable résultant lorsque le GridSplitter ne tient pas compte du min/largeur maximale de la colonne avec une largeur réglé sur "Auto". Le borderBuffer peut devoir être ajusté pour votre cas. Le borderBuffer dans mon cas n'était pas parfaitement logique en fonction des largeurs de géométrie/colonne/bordure - c'était juste le nombre magique qui a fonctionné pour ma mise en page.

Si quelqu'un peut trouver une solution plus propre, j'aimerais l'utiliser à la place. Cette solution me rappelle douloureusement essayer de forcer VB6 à redimensionner les contrôles - beurk. Mais pour l'instant, il vaut mieux avoir des objets sur la première ligne de ma grille de se cacher en raison de l'emballage inattendu.

1

J'ai eu ce comportement indésirable d'arrêter en changeant la * dans le ColumnDefinition à Auto et 240-*.

+0

Merci pour votre réponse. Définir la colonne avec auto n'est pas le comportement que je veux pour ma grille. L'une ou l'autre des colonnes doit avoir le *, ce qui le remplit dans l'espace. Auto n'a pas ce comportement. – SaphuA

+0

Oui, vous avez raison! J'ai expérimenté un peu plus et cette fois je l'ai trouvé pour de vrai je pense ... – Dabblernl

+0

Merci encore, mais ça ne marche pas non plus :) Je peux maintenant faire glisser le splitter sur le côté droit. – SaphuA

2

Je sais que c'est un peu en retard, mais je viens de rencontrer ce problème, et voici ma solution. Malheureusement ce n'est pas assez général, il ne fonctionne que pour une grille à deux colonnes, mais il peut probablement être adapté plus loin. Cependant, il résout le problème décrit et le mien, alors voici:

La solution consiste en une bidouille ou une solution de contournement, mais vous voulez l'appeler. Au lieu de déclarer MinWidth pour les colonnes gauche et droite, vous déclarez une valeur MinWidth et une valeur MaxWidth pour la première colonne. Cela signifie que GridSplitter ne se déplacera pas à droite d'un emplacement défini. Jusqu'ici tout va bien.

Le problème suivant est que si nous avons un conteneur redimensionnable (la fenêtre dans mon cas), cela ne suffit pas. Cela signifie que nous ne pouvons pas agrandir la colonne de gauche autant que nous le voulons, même s'il y a beaucoup d'espace pour le second. Heureusement, il existe une solution: se lier à la grille ActualWidth et utiliser un convertisseur d'addition. Le paramètre du convertisseur sera en fait la Largeur Min souhaitée pour la colonne de droite, évidemment la valeur négative, puisque nous devons la soustraire de la Largeur de la Grille. Vous pouvez également utiliser un SubtractConvertor, mais cela dépend de vous.

va ici le XAML et le code:

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

et le convertisseur:

[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 
} 

J'espère que cette aide,

Mihai Drebot