Как сохранить постоянный FontSize в WPF Viewbox?

У меня есть Viewbox с рядом TextBlock, которые идеально масштабируются и позиционируются ViewBox. Что-то вроде этого:

<Viewbox Stretch="Uniform">
    <Canvas Width="100" Height="100">
        <Ellipse Width="100" Height="100" Stroke="Black"/>
        <TextBlock Width="100" TextAlignment="Center" FontSize="12">Top Center</TextBlock>
    </Canvas>
</Viewbox>

Если пользователь изменяет размер Viewbox, его содержимое идеально масштабируется, чтобы соответствовать. Однако я хотел бы сохранить FontSize до 12 независимо от фактического размера Viewbox.

Как я могу это сделать? Могу ли я сделать это в XAML без привязки к событию Resize?


person Hallgrim    schedule 06.01.2010    source источник


Ответы (2)


ViewBox не позволит вам сохранить постоянный размер шрифта, это просто не то, как это работает. Для этого вам нужно поместить текст за пределы окна просмотра:

<Grid>
    <Viewbox Stretch="Uniform">
        <Canvas Width="100" Height="100">
            <Ellipse Width="100" Height="100" Stroke="Black"/>
        </Canvas>
    </Viewbox>
    <TextBlock TextAlignment="Center" FontSize="12">Top Center</TextBlock>
</Grid>

Обратите внимание, что я удалил свойство Width из TextBlock, я просто позволил ему растянуться на ширину сетки, позволив выравниванию текста позаботиться о центрировании.

Или вы можете проявить творческий подход и привязать свойство FontSize к ActualWidth из ViewBox и соответствующим образом масштабировать его, например:

Конвертер:

class ViewBoxConstantFontSizeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (!(value is double)) return null;
        double d = (double)value;
        return 100 / d * 12;
    }

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

Использование:

<Window.Resources>
    ...
    <local:ViewBoxConstantFontSizeConverter x:Key="conv"/>
</Window.Resources>
...
<Viewbox Name="vb" Stretch="Uniform">
    <Canvas Width="100" Height="100">
        <Ellipse Width="100" Height="100" Stroke="Black"/>
        <TextBlock Width="100" TextAlignment="Center"
                   FontSize="{Binding ElementName=vb, 
                                      Path=ActualWidth, 
                                      Converter={StaticResource conv}}">
            Top Center
        </TextBlock>
    </Canvas>
</Viewbox>
person Aviad P.    schedule 06.01.2010
comment
Спасибо. Думаю, я слишком упростил свой пример. Мне нужно, чтобы Viewbox позаботился о положении моего текста, но не о FontSize. - person Hallgrim; 07.01.2010
comment
Добавил альтернативу моему ответу, попробуйте. Это немного чересчур креативно, но может сработать :) - person Aviad P.; 07.01.2010
comment
Впечатляющий! Это сработало, но я надеялся на что-то более простое. - person Hallgrim; 09.01.2010
comment
Вы также можете сделать более общее решение, которое представляет собой окно просмотра внутри окна просмотра с внутренними размерами окна просмотра, связанными с внешними, с аналогичным масштабированием для каждого измерения. - person Aviad P.; 09.01.2010
comment
также можно использовать StretchDirection=DownOnly, если вы просто не хотите, чтобы он подходил, если он большой. - person eran otzap; 26.03.2014

Это тоже может быть легко исправить.

<Viewbox StretchDirection="DownOnly" >
     <Label Content="Enable" FontSize="10" FontStretch="Normal" />
</Viewbox>
person Pitka    schedule 04.03.2015