【问题标题】:WPF dynamic layout: how to enforce square proportions (width equals height)?WPF动态布局:如何强制执行正方形比例(宽度等于高度)?
【发布时间】:2010-06-05 19:18:55
【问题描述】:

我正在学习 WPF,但不知道如何使我的按钮变成方形。

这是我的 XAML 标记:

<Window x:Class="Example"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="368" Width="333">
  <Window.Resources>
    <Style x:Key="ToggleStyle" BasedOn="{StaticResource {x:Type ToggleButton}}"
                            TargetType="{x:Type RadioButton}">
    </Style>
  </Window.Resources>
  <RadioButton Style="{StaticResource ToggleStyle}">
        Very very long text
  </RadioButton>
</Window>

WidthHeight 属性指定显式值似乎是一个错误的想法——按钮应该根据其内容自动计算其尺寸,但保持其宽度和高度相等。这可能吗?

【问题讨论】:

标签: wpf xaml


【解决方案1】:

试试这个 - 它似乎在 Kaxaml 中工作:

<Button 
    MinWidth="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" 
    MinHeight="{Binding ActualWidth, RelativeSource={RelativeSource Self}}">
  Some content
</Button>

(为了测试,我在按钮内放置了一个 TextBox,因为这是一种无需重新解析 Xaml 即可轻松更改内容大小的方法。)

编辑:抱歉,可能应该将其指定为与您的示例相匹配的样式:

<Style TargetType="Button" x:Key="SquareButton">
  <Setter Property="MinWidth" Value="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" />
  <Setter Property="MinHeight" Value="{Binding ActualWidth, RelativeSource={RelativeSource Self}}" />
</Style>

【讨论】:

  • 有什么方法可以做同样的事情,但不是最小,而是最大?
  • 你应该问一个单独的问题;我不确定您要达到的目标。这个 sn-p 强制一个按钮是围绕其内容的方形;你想达到什么目标?
  • 我已经写好了答案:stackoverflow.com/questions/29620938/…
  • 这个方案唯一的问题是控件可以增长,但不能缩小。所以如果窗口变大,控件会变大,但是当窗口缩小时,控件会保持较大的大小。
  • 是的,它也破坏了设计器,如果你使用它并在设计器中调整窗口大小,我不会推荐这个解决方案。
【解决方案2】:

当前接受的答案不能增长和缩小。我想我找到了更好的方法,通过使用矩形(均匀拉伸)定义自定义样式。

<Style x:Key="SquareButton" TargetType="Button">
    <Setter Property="Foreground" Value="White"/>
    <Setter Property="Background" Value="#3a3a3a" />
    <Setter Property="BorderBrush" Value="#5a5a5a"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">

                <Border HorizontalAlignment="Center">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="auto"/>
                        </Grid.ColumnDefinitions>
                        <Rectangle Stretch="Uniform"
                                         Stroke="{TemplateBinding BorderBrush}"
                                         StrokeThickness="4"
                                         Margin="0" 
                                         Fill="{TemplateBinding Background}" 
                                         Panel.ZIndex="1"
                                         />
                        <ContentPresenter Margin="10" 
                           HorizontalAlignment="Center" 
                           VerticalAlignment="Center" 
                           Panel.ZIndex="2" />
                    </Grid>
                    </Border>

            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="#4a4a4a"/>
        </Trigger>
    </Style.Triggers>
</Style>

顺便说一句,您也可以通过这种方式创建一个完美的圆形按钮。只需将 Rectangle 替换为 Ellipse。

【讨论】:

    【解决方案3】:

    我想你想将按钮的宽度绑定到它的高度,像这样:

    <Button Name="myButton"
    Width="{Binding ElementName=myButton, Path=Height}"
    Height="100">
    Button Text
    </Button>
    

    【讨论】:

    • 我认为 Gart 希望它仍然自动调整为内容,这有点难以完成。另外,您可以使用RelativeSource={RelativeSource Self},而不是使用ElementName,这样更容易移植。
    【解决方案4】:

    @Dan Pruzey 的回答很好,但如果窗口缩小,并没有缩小正方形。我发现最好的方法是将高度设置为自动,将宽度设置为该高度:

    <Button Height="Auto" Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"/>
    

    在调整我的窗口大小时,这使按钮保持为正方形。希望这对某人有所帮助。

    【讨论】:

      【解决方案5】:

      对于您希望按钮展开和缩小的情况,我找到了一个更简单的解决方案,通常是在其文本更改时:

         <RadioButton  Style="{StaticResource ToggleStyle2}" 
                 HorizontalAlignment="Center" VerticalAlignment="Center"
                 HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
                 Width="{Binding Path=ActualWidth, ElementName=txtblck_innerText }"
                 Height="{Binding Path=ActualWidth, ElementName=txtblck_innerText }">
                 
                  
                 <TextBlock x:Name="txtblck_innerText" 
                       MinWidth="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" >
                      Very very long text.........
                 </TextBlock>
          </RadioButton>
      
      

      如问题中所述,当按钮的大小由其内容强加(来自内部)时,上述解决方案适用。

      但是,如果您想要一个方形按钮,其大小是由其所在位置强加(来自外部),例如,大小对于包含按钮的网格单元,解决方案可能是:

           <RadioButton Style="{StaticResource ToggleStyle2}"
                HorizontalAlignment="Center" VerticalAlignment="Center"
                HorizontalContentAlignment="Center" VerticalContentAlignment="Center">
               <Viewbox Stretch="Uniform">
                  <Border Width="20" Height="20">
                     <Viewbox Stretch="Uniform">  
                        <TextBlock x:Name="txtblck_innerText">
                               Very very long text...........
                        </TextBlock>                       
                     </Viewbox>
                  </Border>
               </Viewbox>  
           </RadioButton>
      

      【讨论】:

        猜你喜欢
        • 2013-06-17
        • 1970-01-01
        • 1970-01-01
        • 2011-07-23
        • 1970-01-01
        • 2019-04-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多