1

I have written a toy WPF application with a Button and an ItemsControl. Each time you click the Button, the string "AnotherWord" gets added to the ItemsControl. Now, the ItemsControl is displayed as horizontally oriented StackPanel with a fixed width (500 pixels). This means that when you click the button a certain number of times (actually six times), the newly added string gets clipped, like this:

"AnotherWord AnotherWord AnotherWord AnotherWord AnotherWord AnotherWo"

This happens when the FontSize is 13; if you lower it to 12.7 then there's room for the sixth occurence of "AnotherWord". My question is: Is there a way to make this adjustment at runtime so that you avoid the overflow?

EDIT:

In the context of the question, the fixed width of the StackPanel is obligatory - we cannot use more than the 500 pixels we have. Another requirement that the font must never become bigger than 13.

Here is all the code I wrote:

<!-- MainWindow.xaml -->
<Window x:Class="FontSize.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
         DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Window.Resources>
        <DataTemplate x:Key="labelTemplate">
            <Label FontSize="13" Content="AnotherWord"></Label>
        </DataTemplate>
        <ItemsPanelTemplate x:Key="panelTemplate">
            <StackPanel Orientation="Horizontal" Width="500" Height="50" />
        </ItemsPanelTemplate>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
            <ItemsControl Grid.Row="0" ItemsSource="{Binding Path=MyStrings}" ItemTemplate="{StaticResource labelTemplate}" 
                ItemsPanel="{StaticResource panelTemplate}" />
        <Button Grid.Row="1"  Click="Button_Click"></Button>
    </Grid>
</Window>

// MainWindow.xaml.cs
using System.Collections.ObjectModel;
using System.Windows;

namespace FontSize
{
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            MyStrings = new ObservableCollection<string>();
        }

        public ObservableCollection<string> MyStrings
        {
            get { return (ObservableCollection<string>) GetValue(MyStringsProperty); }
            set { SetValue(MyStringsProperty, value); }
        }

        private static readonly DependencyProperty MyStringsProperty =
            DependencyProperty.Register("MyStrings", typeof (ObservableCollection<string>), typeof (Window));

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MyStrings.Add("AnotherWord");
        }
    }
}
user181813
  • 1,861
  • 6
  • 24
  • 42
  • 1
    discussed here: http://stackoverflow.com/questions/9264398/how-to-calculate-wpf-textblock-width-for-its-known-font-size-and-characters – paul Apr 17 '12 at 13:40
  • @paul your link only talks about how to calculate the size. While this is one thing that will need to be done, it is not an answer to this question. I for one would like to know if someone has a utility to do this. – Bahri Gungor Apr 17 '12 at 14:07
  • The WPF layout engine can do fluent layouts by expanding and contracting visual elements. However, adjusting the font size of text elements is not part of that mechanic. You will have to come up with your own algorithm. – Martin Liversage Apr 19 '12 at 08:11

1 Answers1

4

Put your ItemsControl in a Viewbox and play with the following properties:

  • MaxWidth
  • MaxHeight
  • Stretch
  • StretchDirection

Edit

And remove the Width & Height property of your StackPanel.

Edit 2

Try something like that:

<!-- MainWindow.xaml -->
<Window x:Class="FontSize.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
         DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Window.Resources>
        <DataTemplate x:Key="labelTemplate">
            <Label FontSize="13" Content="AnotherWord"></Label>
        </DataTemplate>
        <ItemsPanelTemplate x:Key="panelTemplate">
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Viewbox Grid.Row="0" MaxWidth="500" Stretch="Uniform">
            <ItemsControl 
                ItemsSource="{Binding Path=MyStrings}"
                ItemTemplate="{StaticResource labelTemplate}" 
                ItemsPanel="{StaticResource panelTemplate}" />
        </Viewbox>
        <Button Grid.Row="1"  Click="Button_Click"></Button>
    </Grid>
</Window>

Edit 3

Change the horizontal alignment of the Viewbox so it isn't stretched to fill the grid. I've put "Center", replace by whatever you want.

...
<Viewbox 
    HorizontalAlignment="Center" 
    StretchDirection="DownOnly"
    Grid.Row="0"
    MaxWidth="500"
    Stretch="Uniform">
...
Nicolas Repiquet
  • 9,097
  • 2
  • 31
  • 53
  • Well, in the context of this question, we cannot use more than the 500 pixels we have. Sorry for not making this clear; I've now added this requirement to the question. – user181813 Apr 18 '12 at 03:40
  • @user181813 Set the `MaxWidth` property of the `ViewBox` to 500. As the `StackPanel` grows over 500, the `ViewBox` will stretch it to fit. This will result in what you are looking for. – Nicolas Repiquet Apr 18 '12 at 06:26
  • Well, I tried to write this: ` `. I got this exception: "VisualTree of ItemsPanelTemplate must contain a Panel. 'System.Windows.Controls.Viewbox' is not a Panel." – user181813 Apr 19 '12 at 08:00
  • Your answer nearly does what I want - the only issue is that the font is bigger than 13 when you click the button the first few times. I have updated the question to require a maximum font size of 13. – user181813 Apr 19 '12 at 08:48
  • Unfortunately, changing the `HorizontalAlignment` doesn't seem to fix the problem with big font sizes. – user181813 Apr 19 '12 at 09:25
  • @user181813 Ok, add `StretchDirection="DownOnly"` to the `Viewbox`. I've tested this time :) – Nicolas Repiquet Apr 19 '12 at 09:49