拉伸控制填写的ItemsControl
-
13-09-2019 - |
题
我试图写它创建了一个可调整大小的主窗口内的一组按钮的一个简单的WPF学习项目。还有就是要为每一个条目的Button
集合中,而集合的内容可能会在运行时有所不同。我想的按钮来填充整个窗口(例如,1按钮@ 100%的宽度,2个按钮@ 50%的宽度,3个按钮@ 33%的宽度,等等都在100%的高度)。什么我至今写一个简化版本是:
<ItemsControl x:Name="itemscontrolButtons" ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Tag="{Binding}">
<TextBlock Text="{Binding}" />
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
...
List<string> listButtonTexts = new List<string>() { "Button1", "Button2" };
...
itemscontrolButtons.DataContext = listButtonTexts;
这导致这样的:
我已无法使按钮被拉伸以适应宽度和我尝试使用一个Grid
代替StackPanel
是徒劳的。
然后,作为一个可选的改进,我希望了解如何调整它使得如果存在,他们不能适当地配合在一行或大于阈窄很多按钮,它将换到一个新行的建议(从而减半按钮高度如果从1到2排去)。
我想强调的是,我想知道如何做到这一点的 WPF方式的。我知道我可以消耗窗口调整消息,并明确地调整控制,这就是如何我会用MFC或WinForms的做了,但是从我读过不是如何这样的事情应该用WPF来完成。
解决方案
更换的项目控制的一个UniformGrid面板,这将大小所有的孩子,所以一切完全适合:
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
其他提示
我是能够建立在尼尔回答履行我的可选标准允许WPF管理与多行拉伸。
首先,你必须能够改变模板的 UniformGrid 的属性。要做到这一点,你需要一个参考存储它。有用于完成多种方法这。我选择处理的加载事件的 UniformGrid 并存储此时的参考。
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" Loaded="UniformGrid_Loaded" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
和在后面的代码:
UniformGrid uniformgridButtons;
private void UniformGrid_Loaded(object sender, RoutedEventArgs e)
{
uniformgridButtons = sender as UniformGrid;
}
然后,根据你所希望的任何标准处理的 SizeChanged将事件和调整的行参数。
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
if ((uniformgridButtons != null) && (this.Width > 0))
{
// Set row count according to your requirements
uniformgridButtons.Rows = (int)(1 + ((this.MinWidth * iButtonCount) / this.Width));
}
}
因此,这使得WPF管理拉伸像尼尔的答案,但可以让你明确调整的行数。上面的代码给出了这样的结果:
(动画样本这里)
<强>更新2009/08/28:强>
我调整我的学习应用程序,使得ItemsControl
是在一个单独的DataTemplate
一个ResourceDictionary
。然而,事件如Loaded
不能在外部ResourceDictionary
XAML文件来处理,因为它没有后台代码(通常情况下)。因此,我需要使用不同的技术来缓存参照UniformGrid
。
我代替艾伦·黑格的FindItemsPanel
方法(10回复)。首先,我取代了ItemsControl
用:
<ContentPresenter x:Name="contentpresenterButtons" Content="{Binding obscolButtons}" />
然后在我ResourceDictionary
,我把ItemsControl
在DataTemplate
:
<DataTemplate DataType="{x:Type local:Buttons}">
<ItemsControl ...
</DataTemplate>
最后,我所存储的参考模板UniformGrid
像这样:
private void Window_Loaded(object sender, RoutedEventArgs e) {
uniformgridButtons = FindItemsPanel<UniformGrid>(contentpresenterButtons);
// Also call the code in Window_SizeChanged which I put in another method
}
这工作只是同我以前的解决方案,但没有在ResourceDictionary
需要一个事件处理程序。
<!-- width must be explicitly set for this example -->
<StackPanel
Name="MyStack"
Orientation="Horizontal"
Width="250"
Load="Window_Loaded">
<Button/>
<Button/>
<Button/>
</StackPanel>
public void Window_Loaded(object sender, RoutedEventArgs e)
{
UIElementCollection elements = MyStack.Children;
int count = elements.Count;
foreach (UIElement element in elements)
{
if (element is Button)
((Button)element).Width = MyStack.Width / count;
}
}