WPF按钮相同/推荐宽度

时间:2010-04-17 13:36:40

标签: wpf user-interface

假设您有一个带有多个按钮的窗口,例如确定/取消或是/否/取消。所有按钮的宽度必须相同。显然,这可以通过猜测一个数字并将所有数字硬连接到该数字来完成。

有没有更好的方法来做到这一点,一个会考虑首选/推荐的尺寸(Ok按钮应该有多宽?这不是一个修辞问题,我实际上不知道答案!) ,最长字幕的文本需要什么,如果字体大小增加会发生什么?

6 个答案:

答案 0 :(得分:9)

有几种方法可以做到这一点:

1)使用网格进行布局。每个Button都有自己的Column,它是星号。这样,所有列的大小都相同:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Button Grid.Column="0">Yes</Button>
    <Button Grid.Column="1">No</Button>
    <Button Grid.Column="2">Cancel</Button>
</Grid>

2)您可以将一个项目作为“主要大小”,并将所有其他项目的宽度绑定到此项目的宽度。

<StackPanel Orientation="Horizontal">
    <Button Name="MasterButton" Width="100">Yes</Button>
    <Button>
        <Button.Width>
            <Binding ElementName="MasterButton" Path="Width"/>
        </Button.Width>
        No
    </Button>
</StackPanel>

编辑:在实际代码中,您可能会有Width =“Auto”。由于其他宽度基于“主宽度”,因此应选择宽度最宽(最宽文本)的按钮。

答案 1 :(得分:7)

另一种更简单的方法是使用SharedSizeGroupColumnDefinition类的RowDefinition属性。

WPF网格中的列(和行)可以自动调整大小以适应其内容 - 使用SharedSizeGroup时,具有相同组名的列共享其调整大小逻辑。

Xaml看起来像这样......

<Grid Grid.IsSharedSizeScope="True">

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition SharedSizeGroup="Buttons" />
        <ColumnDefinition SharedSizeGroup="Buttons" />
        <ColumnDefinition SharedSizeGroup="Buttons" />
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <Button Grid.Column="1"
            HorizontalAlignment="Stretch"
            VerticalAlignment="Center"
            Content="Ok"
            Margin="4" />

    <Button Grid.Column="2"
            HorizontalAlignment="Stretch"
            VerticalAlignment="Center"
            Content="Cancel"
            Margin="4" />

    <Button Grid.Column="3"
            HorizontalAlignment="Stretch"
            VerticalAlignment="Center"
            Content="Long Button Caption"
            Margin="4" />
</Grid>

答案 2 :(得分:4)

使用“主”控件,如Daniel的答案,但绑定到“ActualWidth”属性而不是“Width”:

<StackPanel Orientation="Horizontal">
    <Button Name="MasterButton">Yes</Button>
    <Button>
        <Button.Width>
            <Binding ElementName="MasterButton" Path="ActualWidth"/>
        </Button.Width>
        No
    </Button>
</StackPanel>

这样,在最小和最大宽度之后,在运行时从主控件获取值,并且已考虑所有其他布局计算。绑定到“Width”绑定到您在编译时放入属性的任何内容,这可能不是实际使用的宽度。

此外,绑定可以写得更短

<Button Width="{Binding ElementName=MasterButton, Path=ActualWidth}"/>

答案 3 :(得分:2)

根据Windows 7和Windows Vista的MS用户体验互动指南(p61),命令按钮的标准尺寸为50x14 DLU实际尺寸(75x23像素)。指南进一步建议您“尝试使用[这些]默认宽度和高度。”显然,如果您需要更宽的宽度来贴合透明标签,那么请选择更宽的宽度。

答案 4 :(得分:0)

在最常见的情况下,您要创建一个 您的部分中的样式,然后根据需要应用此样式。现在,当您更改样式时,所有按钮都会更改。

或者您可以更改按钮的内容,以便自动调整文本。

答案 5 :(得分:0)

如果你有一个固定数字或固定的按钮布局,这些答案是很好的,但如果像我一样有一个动态数量的按钮来自一个绑定并包含在ItemsControl中,那么这是不可行的。但是有一种简单的方法,它仍然涉及使用Grid的sharedsize属性。

的DataTemplate:

<DataTemplate x:Key="ODIF.Mapping">
    <Button HorizontalContentAlignment="Left" Background="#FFEEEEEE" BorderBrush="#FFBDBDBD">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" SharedSizeGroup="PluginButtonsWidth"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" SharedSizeGroup="PluginButtonsIconHeight"/>
                <RowDefinition Height="Auto" SharedSizeGroup="PluginButtonsNameHeight"/>
            </Grid.RowDefinitions>
            <Image Width="32" Height="32" Source="{Binding PluginIcon}" RenderOptions.BitmapScalingMode="HighQuality"/>
            <TextBlock Grid.Row="1" Text="{Binding PluginName}"/>
        </Grid>
    </Button>
</DataTemplate>

父容器:

<ItemsControl ItemsSource="{Binding MappingPlugins, ElementName=page}" ItemTemplate="{StaticResource ODIF.Mapping}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Grid.IsSharedSizeScope="True"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

基本上按钮的内容本身可以是一个Gird,然后您可以根据需要放置标签和图标,但即使按钮不在同一个网格中(它们各自都是自己的),网格仍然可以共享它只要将ItemsControl的根容器(Grid.IsSharedSizeScope)属性设置为True即可。

这会强制每个按钮的内容网格基于最大的按钮,但不必将按钮本身放在预定义的网格中。