Триггер стиля WPF

Я изменяю FontSize текста в триггере Style, это также приводит к изменению размера элемента управления, содержащего текст. Как я могу изменить размер шрифта, не влияя на размер родителя?


person Aidan    schedule 26.11.2008    source источник


Ответы (6)


Хороший трюк, чтобы изолировать элемент от его родительского макета, — это поместить элемент в Canvas.

В приведенной ниже разметке есть две копии вашего элемента. Первая скрыта и устанавливает размер вашего элемента управления. Вторая видна, но заключена в Canvas, поэтому размер ее макета не влияет на родительский элемент.

<Parent>
  <Grid>
    <Element Visibility="Hidden"/>
    <Canvas>
      <Element />
    </Canvas>
  <Grid>
</Parent>
person Ifeanyi Echeruo    schedule 04.03.2009

Вы можете увеличить Padding одновременно с уменьшением FontSize — это приведет к тому, что расчетная высота кнопки останется прежней:

<StackPanel>
    <Button Content="ABC">
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="FontSize" Value="20"/>
                <Style.Triggers>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="FontSize" Value="12"/>
                        <Setter Property="Padding" Value="5"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>
    <Button Margin="0,20" Content="123" FontSize="20"/>
    <Button Content="Do Re Mi" FontSize="20"/>
</StackPanel>

Вы можете сделать обратное и установить отрицательное значение Padding, если FontSize также увеличивается.

Вы также можете использовать привязку от FontSize к Padding, чтобы выполнить то же самое в общем случае, но если вы имеете дело только с фиксированным набором FontSizes, было бы проще просто жестко закодировать его, как указано выше.

person Robert Macnee    schedule 10.12.2008

Нет абсолютно никакой необходимости в жестко закодированных ширинах, сумасшедших переопределениях измерений, хитрых привязках или чем-то в этом роде.

Решение на самом деле невероятно простое. Вместо изменения размера шрифта в триггере стиля создайте простой шаблон управления для кнопки с применением RenderTransform к элементу презентатора содержимого. Добавьте ScaleTransform в RenderTransform. Внутри определения триггера IsPressed установите вертикальный и горизонтальный масштабы ScaleTransform на меньшее значение, скажем, 0,8.

Использование RenderTransform сохранит макет нажатой кнопки таким же, поэтому он не повлияет на положение других элементов. Напротив, использование LayoutTransform фактически вызвало бы сжатие контейнера кнопок, а метод ArrangeOverride родительского контейнера заставил бы соседние кнопки перемещаться, чтобы заполнить дополнительное пространство.

Я сейчас очень занят, поэтому я оставлю фактическую реализацию на ваше усмотрение! ;-)

http://msdn.microsoft.com/en-us/library/system.windows.media.scaletransform.aspx

person Community    schedule 09.02.2010

Я создаю ControlTemplate для ButtonControl, чтобы он выглядел как метка (плоский текст, без границ) с триггерами для IsKeyboardFocused, IsPressed, IsDefaulted и т. д.

IsPressed определен для уменьшения FontSize (по умолчанию 30) до 28. Чтобы дать эффект нажатой анимации.

Одним из вариантов использования этих кнопок является горизонтальная StackPanel кнопки, разделенная вертикальными разделителями. Когда триггер IsPressed срабатывает для кнопки и изменяется ее размер, изменяется весь ряд кнопок, что не является приятным визуальным эффектом.

Я предпочитаю решение на основе шаблонов, чтобы избежать введения новых элементов управления для обеспечения переопределений. Единственная проблема с жестко закодированным подходом к размеру - это интернационализация, другие языки увеличат исходный размер.

Решение, которое я собираюсь использовать, - установить minWidth в C # после того, как DesiredSize кнопки был рассчитан. Обратите внимание, что Width имеет значение NaN даже после рендеринга кнопки, следовательно, использование/существование DesiredSize. Позже я попробую XAMLize C#.

person Aidan    schedule 27.11.2008

Какой вид контроля вы используете? Если это HeaderedControl, такой как GroupBox или TabItem, вам нужно специально установить HeaderTemplate следующим образом:

<DataTemplate x:Key="MyHeaderTemplate">
  <TextBlock Text="{Binding}" Fontsize="14" FontWeight="Bold" />
</DataTemplate>
person Micah    schedule 26.11.2008

Я могу придумать пару вещей, которые вы могли бы попробовать:

  • Вы можете переопределить проход измерения элемента управления: когда элемент управления визуализируется в WPF, он проходит два прохода. Первый — это «проход измерения», когда элемент управления определяет размеры, которые он хочет сделать. Второй - это «переход аранжировки», где он фактически устанавливает контроль. WPF предоставляет метод с именем MeasureOverride. Если вы переопределяете этот метод, вы можете обеспечить собственное поведение, которое можно использовать для настройки размера элемента управления.

    Примечание. Я полагаю, что вам придется вызывать метод Measure для всех ваших дочерних элементов управления во время этого переопределения, чтобы ваш элемент управления располагался правильно.

  • Жестко закодируйте высоту и ширину в элементе управления — это переопределит DesiredSize элемента управления вашими значениями. Хотя, как правило, это не самая лучшая идея, она будет работать.

person NigelTufnel    schedule 26.11.2008