代码之家  ›  专栏  ›  技术社区  ›  rwallace

WPF按钮相同/建议宽度

  •  8
  • rwallace  · 技术社区  · 14 年前

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

    有没有更好的方法可以做到这一点,即考虑到首选/推荐的尺寸(确定按钮应该有多宽)?这不是一个反问题,我真的不知道答案!),最长标题的文本需要什么,如果字体大小增加会发生什么?

    6 回复  |  直到 8 年前
        1
  •  9
  •   Daniel Rose    14 年前

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

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

    <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”。由于其他宽度基于“主控形状宽度”,因此应选择宽度最大(文本最宽)的按钮。

        2
  •  7
  •   Bevan    13 年前

    另一种可能更简单的方法是使用 SharedSizeGroup 属性上 ColumnDefinition RowDefinition 类。

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

    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>
    
        3
  •  4
  •   Alexander Rautenberg    13 年前

    使用“master”控件,如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}"/>
    
        4
  •  2
  •   Michael Zuschlag    14 年前

    根据Windows7和WindowsVista(p61)的MS用户体验交互指南,命令按钮的标准尺寸为50x14 DLU实际尺寸(75x23像素)。指南还建议您“尝试使用[这些]默认的宽度和高度”。显然,如果您需要更大的宽度来适应清晰的标签,则需要更大的宽度。

        5
  •  0
  •   Dave    14 年前

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

    也可以更改按钮的内容,使其自动调整为文本。

        6
  •  0
  •   Wobbles    8 年前

    如果你有一个固定的按钮编号或固定的布局,这些答案是很好的,但是如果像我一样,有一个动态的按钮编号来自绑定并包含在 ItemsControl 那么这是不可行的。但是有一个简单的方法,它仍然涉及使用网格的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>
    

    本质上,按钮的内容本身可以是一个网格,然后您可以根据需要放置标签和图标,但即使按钮不在同一个网格中(它们各自都是自己的),只要设置根容器的( 项目控制 的性质 Grid.IsSharedSizeScope 成真。

    这将强制每个按钮的内容网格根据最大的按钮保持相同的精确大小,而不必将按钮本身放在预定义的网格中。