在其容器内约束WPF元素宽度

时间:2012-02-10 15:03:34

标签: wpf xaml wpf-controls

我正在放置一个模板化的Button,其中有一些内容(Image和TextBlocks)在其他控件的Grid中:

<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(甚至更好的完整网格的宽度)没有定义一个absoulte宽度,所以“SpecialButton”仍然可以很好地绘制并忽略它的孩子的溢出。 CSS之类的{overflow:hidden}会很棒......
注意:
我不能允许包装,因为“SpecialButton”高度也是固定的(并且是手动计算的)。

1 个答案:

答案 0 :(得分:4)

一旦习惯,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>

此外,您可能还希望将文本框的工具提示设置为文本的值。如果文本被截断并且用户想要查看它是什么,他们可以将鼠标悬停在按钮上并查找。