Почему эта кнопка WPF растягивается по всему окну?

Кнопка ниже всегда расширяется до ширины TextBlock. Я пробовал StackPanel, DockPanel, Width = "Auto" и т. Д.

Как я могу заставить кнопку расширяться до размера собственного текста (как в HTML), а не до размера текста в ее окружении?

    <DockPanel HorizontalAlignment="Left">
        <Button x:Name="ButtonFavorite"
                DockPanel.Dock="Top"  
                Content="Customers" 
                Margin="10" 
                Width="Auto"
                Click="ButtonFavorite_Click">
        </Button>

        <TextBlock DockPanel.Dock="Top" Text="this is a long text which makes the button stretch across the window, if this text is just a couple words, the button will be smaller, and this drives me up the wall"  Margin="10" TextWrapping="Wrap" />

    </DockPanel>

ОТВЕЧАТЬ:

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

<Window x:Class="Test3784234.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <DockPanel HorizontalAlignment="Left">
        <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" >
            <Button x:Name="ButtonFavorite"
                    Padding="5"
                    Cursor="Hand" 
                    DockPanel.Dock="Top"  
                    Content="Customers" 
                    Margin="10" 
                    Click="ButtonFavorite_Click">
                <Button.ContextMenu>
                    <ContextMenu>
                        <MenuItem x:Name="menuItemReports" Header="Reports" Click="MenuItem_Click" />
                        <MenuItem x:Name="menuItemContracts" Header="Contracts" Click="MenuItem_Click"/>
                        <MenuItem x:Name="menuItemCustomers" Header="Customers" Click="MenuItem_Click" />
                        <MenuItem x:Name="menuItemDocumentation" Header="Documentation Creation Instructions" Click="MenuItem_Click" />
                        <MenuItem x:Name="menuItemEmail" Header="E-Mail" Click="MenuItem_Click" />
                    </ContextMenu>
                </Button.ContextMenu>
            </Button>

        </StackPanel>

        <TextBlock x:Name="TheMessage" DockPanel.Dock="Top" Text="Right-click the 'favorites' button to change its function." Margin="10" TextWrapping="Wrap"/>

    </DockPanel>
</Window>

Ответов (6)

Решение

Что касается вашего раздражения по поводу размера кнопок, это, похоже, нацелено на дизайнера в рабочем процессе дизайнера / разработчика, в то время как вы явно работаете над частью разработчика. В целях разработки я всегда применяю несколько стилей в своем App.xaml, чтобы обеспечить более точный размер кнопок. Например, в теге приложения в вашем файле app.xaml:

<Application.Resources>
  <Style TargetType="Button">
    <Setter Property="MinWidth" Value="60" />
    <Setter Property="MinHeight" Value="23" />
    <Setter Property="Margin" Value="3" />
  </Style>
</Application.Resources>

Что касается вашего актуального вопроса:

Проблема в том, что ваша DockPanel растягивается до ширины текста, и кнопка естественным образом расширяется, чтобы заполнить доступную область. Если вам нужно быстрое и грязное решение, вы можете сделать что-то вроде:

<DockPanel HorizontalAlignment="Left">
    <Button x:Name="ButtonFavorite"
            DockPanel.Dock="Top"  
            Content="Customers" 
            Margin="10" 
            Width="Auto"
            MaxWidth="100"
            Click="ButtonFavorite_Click">
    </Button>
</DockPanel>

Обратите внимание на MaxWidth. Если вы хотите получить более композиционный результат, изолируйте кнопку на другой панели. (Я использую стековую панель, потому что считаю, что кто-то уже использовал сетку в своем примере):

<DockPanel HorizontalAlignment="Left">
    <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
        <Button x:Name="ButtonFavorite"
            Content="Customers" 
            Margin="10" 
            Width="Auto"
            Click="ButtonFavorite_Click" />
    </StackPanel>
    <TextBlock DockPanel.Dock="Top" Text="this is a long text which makes the button stretch across the window, if this text is just a couple words, the button will be smaller, and this drives me up the wall"  Margin="10" TextWrapping="Wrap" />
</DockPanel>

В этом случае мне нравится StackPanel, потому что я использую ее для создания горизонтальной «полосы» кнопок в нижней части окна формы в правом углу.

В качестве другого способа сделать это: вы можете изменить шаблон кнопки, чтобы он по существу был заключен в центрированную StackPanel. Что-то вроде этого:

<Button Content="Back">
    <Button.Template>
        <ControlTemplate>
            <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                <Button Content="{TemplateBinding Content}"></Button>
            </StackPanel>
        </ControlTemplate>
    </Button.Template>
</Button>

Или вы можете добавить стиль в app.xaml (или в любое другое место, где вы храните свои глобальные стили) следующим образом:

<Style TargetType="{x:Type Button}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                    <Button Style="{x:Null}" Content="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type Button}} }" FontWeight="Bold" Padding="5"></Button>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Обратите внимание, что Style="{x:Null}" при добавлении к глобальным стилям важно включить атрибут на кнопку в шаблоне, иначе вы получите бесконечный цикл, когда дело доходит до рендеринга кнопки.

Все, что вам нужно сделать, это установить свойство HorizontalAlignment на вашей кнопке. По умолчанию он растягивается, поэтому заполняет доступное пространство.

<Button x:Name="ButtonFavorite"
        HorizontalAlignment="Left"
        Content="Customers" 
        Margin="10" 
        Width="Auto"
        Click="ButtonFavorite_Click">

Можете ли вы разместить их в сетке из двух столбцов, при этом кнопка будет занимать только один столбец, а текст - два столбца?

Вот пример использования макета сетки в сравнении с DockPanel. Идея состоит в том, чтобы иметь 2 столбца и 2 строки. Поместите кнопку в одну ячейку и сделайте автоматическое изменение размера этой пары строка / столбец. Затем поместите TextBox во вторую строку и охватите оба столбца. По сути, это сделает верхнюю правую ячейку просто заполнителем пространства и достигнет желаемого поведения.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>

    <Button 
        x:Name="ButtonFavorite"
        Grid.Column="0"
        Grid.Row="0"
        Content="Customers" 
        Margin="10" 
        Width="Auto"
        Click="ButtonFavorite_Click">
    </Button>

    <TextBlock 
        Grid.Column="0"
        Grid.ColumnSpan="2"
        Grid.Row="1"
        Margin="10" 
        TextWrapping="Wrap"
        Text="this is a long text which makes the button stretch across the window, if this text is just a couple words, the button will be smaller, and this drives me up the wall" />
</Grid>

Вы можете попробовать изолировать кнопку от основной панели, поместив ее на другую панель.

<DockPanel HorizontalAlignment="Left">
    <Grid DockPanel.Dock="Top">
        <Button x:Name="ButtonFavorite"
                Content="Customers" 
                Margin="10" 
                Width="Auto"
                Click="ButtonFavorite_Click">
        </Button>
    </Grid>

    <TextBlock DockPanel.Dock="Top" Text="this is a long text which makes the button stretch across the window, if this text is just a couple words, the button will be smaller, and this drives me up the wall"  Margin="10" TextWrapping="Wrap" />

</DockPanel>