WPF кнопки одинаковые / рекомендуемая ширина - PullRequest
8 голосов
/ 17 апреля 2010

Предположим, у вас есть окно с несколькими кнопками, такими как Ok / Cancel или Yes / No / Cancel. Все кнопки должны быть одинаковой ширины. Очевидно, что это можно сделать, просто угадав число и подключив их всех к этому числу.

Есть ли лучший способ сделать это, который бы учитывал предпочтительные / рекомендуемые размеры (насколько широкой должна быть кнопка Ok в любом случае? Это не риторический вопрос, я на самом деле не знаю ответа!) что нужно тексту самого длинного заголовка, что произойдет, если размер шрифта будет увеличен и т. д.

Ответы [ 6 ]

9 голосов
/ 17 апреля 2010

Есть несколько способов сделать это:

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>

EDIT: В реальном коде у вас, вероятно, будет Width = "Auto". Поскольку другие значения ширины основаны на «основной ширине», следует выбирать кнопку с самой широкой шириной (самый широкий текст).

7 голосов
/ 18 июля 2011

Другой, возможно, более простой способ сделать это - использовать свойство SharedSizeGroup в классах ColumnDefinition и 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>
4 голосов
/ 07 февраля 2011

Используйте «основной» элемент управления, как в ответе Даниэля, но связывайте с атрибутом «ActualWidth» вместо «Width»:

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

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

Кроме того, привязка может быть написана короче, как

<Button Width="{Binding ElementName=MasterButton, Path=ActualWidth}"/>
2 голосов
/ 19 апреля 2010

В соответствии с Руководством по взаимодействию с пользователем для пользователей MS для Windows 7 и Windows Vista (p61) стандартные размеры для командных кнопок составляют фактический размер DLU 50x14 (75x23 пикселей). Рекомендации также предлагают вам «попытаться работать с [этими] значениями ширины и высоты по умолчанию». Очевидно, что если вам нужно больше ширины, чтобы разместить четкую метку, тогда берите больше ширины.

0 голосов
/ 23 марта 2016

Эти ответы хороши, если у вас есть фиксированный номер или фиксированная раскладка для кнопок, но если, как и у меня, динамическое количество кнопок происходит из привязки и содержится в 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, в котором затем можно размещать ярлыки и значки по мере необходимости, но даже при том, что кнопки не находятся в одной и той же сетке (каждая из них является своей), сетка все равно может делиться ею размер до тех пор, пока для свойства Grid.IsSharedSizeScope корневого контейнера (ItemsControl) установлено значение True.

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

0 голосов
/ 17 апреля 2010

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

Или вы можете изменить содержимое кнопки, чтобы она автоматически изменяла размер текста.

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