WPF GridSplitter Column Width Grow

Oggi mi sono ritorvato a perdere 2 ore su un buco di WPF che mi ha lasciato al quanto shocakto o_O

Partiamo dicendo che un GridSplitter si puo’ realizzare in due modi diciamo
1) Colonna dedicata

<Grid x:Name="LayoutRoot">
    <Grid  x:Name="GridTest">
        <Grid.ColumnDefinitions>
            <ColumnDefinition MinWidth="40" />
            <ColumnDefinition Width="3" />
            <ColumnDefinition MinWidth="50" Width="auto" />
        </Grid.ColumnDefinitions>
        <Border Background="Red" Grid.Column="0" CornerRadius="20"/>
        <Border Background="Red" Grid.Column="2" CornerRadius="20"/>
        <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" Width="5" ResizeBehavior="PreviousAndNext" />
    </Grid>
    <TextBlock Text="{Binding ActualWidth, ElementName=GridTest}" VerticalAlignment="Top" HorizontalAlignment="Left"/>
</Grid>

2) Splitter all’ interno di una colonna

<Grid x:Name="LayoutRoot">
    <Grid  x:Name="GridTest">
        <Grid.ColumnDefinitions>
            <ColumnDefinition MinWidth="40" />
            <ColumnDefinition MinWidth="50" Width="auto" />
        </Grid.ColumnDefinitions>
        <Border Background="Red" Grid.Column="0" CornerRadius="20"/>
        <Border Background="Red" Grid.Column="1" CornerRadius="20"/>
        <GridSplitter Grid.Column="1" HorizontalAlignment="Left" Width="5" />
    </Grid>
    <TextBlock Text="{Binding ActualWidth, ElementName=GridTest}" VerticalAlignment="Top" HorizontalAlignment="Left"/>
</Grid>

In entrambi i casi proposti sopra si verifica che nel caso si faccia il resize verso sinistra, la colonna di destra continua a crescere all’ infinito.
Questo buco si verifica perche’ e’ stato assegnato un MinWidth alla prima colonna.
Continuiamo ad analizzare il caso 2

– Fix 1

<Grid x:Name="LayoutRoot">
    <Grid  x:Name="GridTest">
        <Grid.ColumnDefinitions>
            <ColumnDefinition MinWidth="40" />
            <ColumnDefinition MinWidth="50" Width="0*" />
        </Grid.ColumnDefinitions>
        <Border Background="Red" Grid.Column="0" CornerRadius="20"/>
        <Border Background="Red" Grid.Column="1" CornerRadius="20"/>
        <GridSplitter Grid.Column="1" HorizontalAlignment="Left" Width="5" />
    </Grid>
    <TextBlock Text="{Binding ActualWidth, ElementName=GridTest}" VerticalAlignment="Top" HorizontalAlignment="Left"/>
</Grid>

Utilizzando la lunghezza espressa in *, Width=”0*” il bug non si verifica.
Se si specifica Width=”auto” o Width=”100″ il bug si presenta.

– Fix 2

XAML

<Grid x:Name="LayoutRoot">
    <Grid  x:Name="GridTest">
        <Grid.ColumnDefinitions>
            <ColumnDefinition MinWidth="40" />
            <ColumnDefinition MinWidth="50" Width="auto" MaxWidth="{Binding ActualWidth, ConverterParameter=40, Converter={StaticResource ColumnConverter}, ElementName=Test, Mode=Default}" />
        </Grid.ColumnDefinitions>
        <Border Background="Red" Grid.Column="0" CornerRadius="20"/>
        <Border Background="Red" Grid.Column="1" CornerRadius="20"/>
        <GridSplitter Grid.Column="1" HorizontalAlignment="Left" Width="5" />
    </Grid>
    <TextBlock Text="{Binding ActualWidth, ElementName=GridTest}" VerticalAlignment="Top" HorizontalAlignment="Left"/>
</Grid>

C# Converter

class ColumnConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double GridActualWidth = System.Convert.ToDouble(value);
        double FirstColumnMinWidth = System.Convert.ToDouble(parameter);

        double Result = GridActualWidth - FirstColumnMinWidth;
        if (Result < 0)
            return 0;
        else
            return Result;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Questo converter permette di calcolare il massimo della colonna e con questo trick si risolve il bug di WPF
Non so se il bug e’ presente anche su Silverlight, non l’ ho testato

Annunci

Informazioni su Andrea Regoli

Project Manager .Net Developer WPF WP7 Asp.Net c# javascript ajax SQL sharepoint
Questa voce è stata pubblicata in c#, WPF, xaml e contrassegnata con , , , , . Contrassegna il permalink.

Una risposta a WPF GridSplitter Column Width Grow

  1. That is a really good tip particularly to those fresh to the blogosphere.
    Brief but very precise information… Thanks for
    sharing this one. A must read article!

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...