根据最大按钮的内容均匀大小的按钮
Posted
技术标签:
【中文标题】根据最大按钮的内容均匀大小的按钮【英文标题】:Evenly-sized buttons according to content of largest button 【发布时间】:2011-09-09 03:32:12 【问题描述】:假设我在一个窗口上有两个 WPF 按钮,内容如下:
<Button>OK</Button>
<Button>Cancel</Button>
我希望这些按钮具有相同的宽度,但是在 Content
绑定到给定用户语言的本地化值的情况下,我不知道按钮需要多宽才能适应新的内容。
我如何为这些按钮应用最小宽度,以便最宽的宽度(根据内容)有效地用作两者的MinWidth
,从而保持它们一致?
或者换一种说法:我不希望按钮成为其容器的宽度(除非以巧妙的方式使用容器可以解决我的问题),并且我不希望它们每个都只需根据自己的内容调整大小,因为这会使它们的大小不同。我想要介于两者之间的东西。具有最大内容大小以显示其内容的内容,以及所有其他内容大小相同的宽度,因此宽度都相等。
我希望答案在于将它们放入某种容器中。我知道我可以使用Grid
并让它们填充网格“单元格”,但重点是我也不希望它们太 宽。我知道我可以在按钮的Content_Changed
事件上运行一些代码隐藏并将最小宽度设置为最宽按钮的最小宽度,但我对纯xaml 方法感兴趣。我可能需要创建一个扩展 ItemsControl
的自定义控件,以便在添加新项目或调整其大小时运行代码隐藏并将最宽项目的宽度应用为所有其他项目的 MinWidth
。
非常感谢。
【问题讨论】:
所以你是说你不想使用<ColumnDefinition Width="*"/>
不需要 "Auto"
。
【参考方案1】:
网格
<Grid HorizontalAlignment="Right" Grid.IsSharedSizeScope="true">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A"/>
<ColumnDefinition SharedSizeGroup="A"/>
</Grid.ColumnDefinitions>
<Grid.Children>
<Button Grid.Column="0" Content="OK"/>
<Button Grid.Column="1" Content="Cancel"/>
</Grid.Children>
</Grid>
这可以分解,你只需要在一个共同的祖先上设置IsSharedSizeScope
,例如:
<StackPanel Grid.IsSharedSizeScope="true">
<Grid HorizontalAlignment="Right">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A"/>
</Grid.ColumnDefinitions>
<Grid.Children>
<Button Grid.Column="0" Content="OK"/>
</Grid.Children>
</Grid>
<!-- ... -->
<Grid HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A"/>
</Grid.ColumnDefinitions>
<Grid.Children>
<Button Grid.Column="0" Content="Cancel"/>
</Grid.Children>
</Grid>
</StackPanel>
为防止按钮变得太大,请将网格的HorizontalAlignment
更改为Stretch
以外的其他值或设置MaxWidth
。
【讨论】:
你展示的使用 SharedSizeGroup 的方式我认为比作者接受的答案更有用。谢谢。【参考方案2】:Use UniformGrid
<UniformGrid HorizontalAlignment="Right" Rows="1" Columns="2">
<Button Content="Ok" Grid.Column="0"/>
<Button Content="Cancel" Grid.Column="1"/>
</UniformGrid>
【讨论】:
这个答案的优点是允许您为不需要的按钮设置 Visibility = "Collapsed" 并且整个单元格消失 - 使用 SharedSizeGroup 网格这样做会给您留下一个洞,这可能不是你想要的。加上它的简洁!Grid.Column
和 Grid.Row
被 UniformGrid
忽略,在 Xaml 中按声明顺序添加控件。【参考方案3】:
我喜欢在这种情况下使用包装面板。加载后,我使用linq
从所有孩子那里获得最大宽度。 (假设孩子都是按钮)
xaml
<WrapPanel Name="WP_ButtonSelections" Orientation="Horizontal" HorizontalAlignment="Center" Loaded="WP_ButtonSelections_Loaded"></WrapPanel>
cs
WP_ButtonSelections.Children.Add(new Button() Content = "Hello" );
WP_ButtonSelections.Children.Add(new Button() Content = "Hello World" );
private void WP_ButtonSelections_Loaded(object sender, RoutedEventArgs e)
double maxWidth = WP_ButtonSelections.Children.OfType<FrameworkElement>().Max(elm => elm.ActualWidth);
WP_ButtonSelections.Children.OfType<FrameworkElement>().ToList().ForEach(elm => elm.Width = maxWidth);
我需要一个程序化解决方案。这需要加载事件,因为以编程方式添加的按钮不会在调用WP_ButtonSelections.Children.Add()
时定义ActualWidth
。此解决方案应该使用 xaml 定义的按钮,或者 xaml 和编程的混合。
【讨论】:
以上是关于根据最大按钮的内容均匀大小的按钮的主要内容,如果未能解决你的问题,请参考以下文章