WPF Layout bietet nicht genügend Platz - was nun ?



  • Hai ...

    Auf meinem WINDOW befindet sich ein "Fragebereich - Grid", wovon der untere Teil des Grids für die Antworten vorgesehen ist.

    Die Antworten habe ich als ToggleButtons mit eigenem Style realisiert:

    <!-- Antwort Button Style -->
            <Style
                TargetType="{x:Type ToggleButton}"
                x:Key="AntwortButtonStyle">
    
    			<Setter Property="FontSize" Value="30"></Setter>
    
                <Setter
                    Property="Template">
                    <Setter.Value>
                        <ControlTemplate
                            TargetType="{x:Type ToggleButton}">
    
                            <Border
                                BorderBrush="Black"
                                CornerRadius="6"
    ...
    ...
    

    Das ganze steckt dann in einem ItemsControl ...

    <ItemsControl x:Name="AntwortenBuffer"  ItemsSource="{Binding aktuelleFrage.antworten, Converter={StaticResource AntwortenMischen}}"
                                HorizontalContentAlignment="Center" VerticalContentAlignment="Center" MinWidth="20" MinHeight="20" ScrollViewer.VerticalScrollBarVisibility="Disabled" VerticalAlignment="Top"
        						Grid.Row="1"
        						HorizontalAlignment="Stretch"
        						Background="{x:Null}">
        						<ItemsControl.ItemsPanel>
        							<ItemsPanelTemplate>
        								<WrapPanel x:Name="AntwortenWrap" SizeChanged="AntwortenContainerWrap_SizeChanged" Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center" />
        							</ItemsPanelTemplate>
        						</ItemsControl.ItemsPanel>
        							<!-- Wie sollen die Antworten aussehen -->
        						<ItemsControl.ItemTemplate>
        							<DataTemplate>
                                        <ToggleButton
                                            Click="AntwortButton_Click" x:Name="AntwortButton" Content="{Binding}" Foreground="White" Style="{StaticResource AntwortButtonStyle}" Height="Auto" Margin="2" />
        							</DataTemplate>
    

    Wenn nun zu viele Antworten vorhanden sind, oder die wenigen einfach zu lang - werden diese ja abgeschnitten dargestellt. Genau das möchte ich verhindern, und habe mir gedacht, in diesem Fall "EINFACH :)" die FontSize herabzusetzen, bis der Inhalt dargestellt werden kann.

    Um genau das zu erreichen habe ich dem WrapPanel diese SizeChanged Event spendiert:

    if ( (e.WidthChanged && e.NewSize.Width > FrageBereich.ActualWidth) || (e.HeightChanged && e.NewSize.Height > FrageBereich.ActualHeight) )
                {
                    MessageBox.Show("Antworten werden abgeschnitten. Starte LayoutModus");
    
                    if (e.WidthChanged)
                    {
                        Style s = (Style) this.FindResource("AntwortButtonStyle");
    
                        foreach (Setter setter in s.Setters)
                        {
                            double localValue;
    
                            if (setter.Property == FontSizeProperty)
                            {
                                localValue = (double)setter.Value;
    
                                localValue = --localValue;
    
                                setter.Value = localValue;
    
                                ((WrapPanel)sender).InvalidateArrange();
                                MessageBox.Show("1. Durchgang");
                            }
                        }
                    }
    

    Wobei ich diese Meldung erhalte:

    Sobald ein SetterBase-Objekt verwendet wird (versiegelt ist), kann es nicht mehr geändert werden.

    Ok, das ist also der falsche weg. Wie würdet ihr das angehen ?



  • Statt den Text zu schneiden würde ich eher Horizontale Scrollbars einblenden. (ScrollViewer)



  • Mmh, das wollte ich eigentlich nicht, da es meiner Meinung nach selten zur Optik passt und dem "reflexartige" Beantworten nicht so recht hilfreich ist.

    Ich versuche das ganze nun mit einer eigenen FontSizeProperty,

    protected readonly DependencyProperty quizFontSizeProperty = DependencyProperty.Register("quizFontSize", typeof(double), typeof(AbfragenPanel), new FrameworkPropertyMetadata(18.0, System.Windows.FrameworkPropertyMetadataOptions.AffectsMeasure));
    
    public double quizFontSize
            {
                get
                {
                    return (double)GetValue(quizFontSizeProperty);
                }
    
                set
                {
                    SetValue(quizFontSizeProperty, value);
                }
            }
    

    ...die so gebunden ist:

    <Setter Property="FontSize" Value="{Binding quizFontSize, ElementName=UserControl}"></Setter>
    
    private void AntwortenContainerWrap_SizeChanged(object sender, SizeChangedEventArgs e)
            {
                if ( (e.WidthChanged && e.NewSize.Width > FrageBereich.ActualWidth) || (e.HeightChanged && e.NewSize.Height > FrageBereich.ActualHeight) )
                {
                    MessageBox.Show("Antworten werden abgeschnitten. Starte LayoutModus");
    
                    if (e.WidthChanged)
                    {
                        while (((WrapPanel)sender).ActualWidth > FrageBereich.ActualWidth)
                        {
                            SetValue(quizFontSizeProperty, (quizFontSize = quizFontSize - 1));
                            MessageBox.Show("Wrap: " + ((WrapPanel)sender).ActualWidth + "\nFragebereich: " + FrageBereich.ActualWidth + "\nFontSizeValue: " + quizFontSize);
                        }
                    }
                }
    
            }
    

    Die verringern der Fontsize scheint so zu klappen, allerdings ändert sich die ActualWidth erst nach verlassen des Events. Gibt es eine Möglichkeit die Größe des Panels nach Änderung der FontSize abzufragen ?



  • Okay ...

    ganz simpel:

    if ( (e.WidthChanged && e.NewSize.Width > FrageBereich.ActualWidth) || (e.HeightChanged && e.NewSize.Height > FrageBereich.ActualHeight) )
                {
                    //MessageBox.Show("Antworten werden abgeschnitten. Starte LayoutModus");
    
                    while ( (((WrapPanel)sender).ActualWidth > FrageBereich.ActualWidth) || (((WrapPanel)sender).ActualHeight > FrageBereich.ActualHeight) )
                        {
                            SetValue(quizFontSizeProperty, (quizFontSize = quizFontSize - 1));
                            ((WrapPanel)sender).UpdateLayout();
                        }
                }
    

Anmelden zum Antworten