WPF Style Trigger - PullRequest
       21

WPF Style Trigger

3 голосов
/ 26 ноября 2008

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

Ответы [ 6 ]

7 голосов
/ 04 марта 2009

Хорошая хитрость, позволяющая изолировать элемент от его родительского макета, - поместить элемент в Canvas

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

<Parent>
  <Grid>
    <Element Visibility="Hidden"/>
    <Canvas>
      <Element />
    </Canvas>
  <Grid>
</Parent>
3 голосов
/ 09 февраля 2010

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

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

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

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

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

3 голосов
/ 10 декабря 2008

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

<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>

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

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

1 голос
/ 27 ноября 2008

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

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

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

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

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

0 голосов
/ 26 ноября 2008

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

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

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

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

0 голосов
/ 26 ноября 2008

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

<DataTemplate x:Key="MyHeaderTemplate">
  <TextBlock Text="{Binding}" Fontsize="14" FontWeight="Bold" />
</DataTemplate>
...