Ограничить ширину элемента WPF внутри контейнера - PullRequest
1 голос
/ 10 февраля 2012

Я помещаю шаблонную кнопку с некоторым содержимым внутри нее (как Image, так и TextBlocks) в сетку другого элемента управления:

<SomeControl>
   <Grid>
       <SpecialButton/>
   </Grid>
</SomeControl>

<Style TargetType="{x:Type local:SpecialButton}">>
    ...
    <Setter Property="Template">
        <Setter.Value>
        ...
            <TextBlock/>
            <TextBlock/>
        </Setter.Value>
</Style>

Ширина элемента управления SomeControl является динамической - то есть - она ​​можетдинамически изменяться в зависимости от ширины экрана, ширины контейнера и т. д. Поэтому я использую другой метод для вычисления ширины «SpecialButton».Пока TextBlock внутри кнопки не шире, чем сама кнопка"SpecialButton" идеально соответствует своему размеру контейнеру SomeControl.Однако, если текст TextBlock длиннее ширины «SpecialButton», правая граница «SpecialButton» исчезает, и кнопка выглядит очень плохо.Тем не менее, ширина «SpecialButton» по-прежнему равна ширине его контейнеров, хотя рисунок плохо рассчитывается.Я пытаюсь найти способ сохранить TextBlock (или, что еще лучше, полную ширину Grid) без определения абсолютной ширины, поэтому «SpecialButton» все равно будет хорошо прорисован и проигнорирует переполнение детей.Что-то вроде CSS {overflow: hidden} было бы здорово ...Замечания:Я не могу разрешить перенос, так как высота "SpecialButton" также содержится (и вычисляется вручную).

1 Ответ

4 голосов
/ 13 февраля 2012

Ширина (и высота) в элементах WPF довольно просты, как только вы к этому привыкнете.По умолчанию для вашей сетки установлено значение Авто ширина, что означает, что она будет запрашивать 100% ширины родительского элемента.

Вместо того, чтобы устанавливать максимальный размер, я обычно помещаю элементы, которые я хочу, динамически измерять и размещать в них.сетка и установить сетку строк и размеров столбцов.Поэтому, если я хочу, чтобы что-то занимало 1/3 доступного горизонтального пространства, у меня может быть сетка с двумя столбцами, один с шириной, равной «1 *», а другой - с «2 *» (2/3 - дваждыразмером 1/3), и поместите мой элемент в столбец 1, чтобы он занимал всю доступную ширину.

В вашем случае текст должен быть обрезан, так как он делает все возможное, чтобы отобразить всетекст, и расширяет кнопку за пределы своего контейнера, чтобы сделать это.Существует два варианта встроенной функции обрезки.TextTrimming="CharacterEllipsis" и TextTrimming="WordEllipsis" Просто поместите это в свои текстовые блоки.Я бы поместил текстовые блоки в какой-нибудь контейнер, чтобы они были отдельными.Если первое имеет достаточно длинное содержимое, оно может полностью оттолкнуть другое.

Размер элемента

<Window
    x:Class="MainWindow"
    x:Name="Window"
    Title="MainWindow"
    Width="640" Height="480">
    <Grid x:Name="LayoutRoot" DataContext="{Binding}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>
        <local:SomeControl Margin="8,8,8,0"/>
    </Grid>
</Window>

Обрезка текста

<ControlTemplate x:Key="ButtonBaseControlTemplate1" TargetType="{x:Type ButtonBase}">
    <Microsoft_Windows_Themes:ButtonChrome x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Fill="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RenderDefaulted="{TemplateBinding Button.IsDefaulted}" SnapsToDevicePixels="True" ThemeColor="Metallic">
        <TextBlock Text="{TemplateBinding Content}" TextTrimming="WordEllipsis" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Microsoft_Windows_Themes:ButtonChrome>
    <ControlTemplate.Triggers>
        <Trigger Property="IsKeyboardFocused" Value="True">
            <Setter Property="RenderDefaulted" TargetName="Chrome" Value="True"/>
        </Trigger>
        <Trigger Property="ToggleButton.IsChecked" Value="True">
            <Setter Property="RenderPressed" TargetName="Chrome" Value="True"/>
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...