我对wpf和c#完全是新手,所以请原谅这是否是一个超级微不足道的问题。我正在尝试创建一个相当简单的控件。
此网格将始终具有连续的数字,前面有一个颜色矩形。单击灰色矩形将更改其颜色,并将文本设置为粗体(稍后我将处理这些触发器)。
目前,我只需要弄清楚如何动态创建此控件。程序启动时,需要一次创建此控件,然后大小不会改变。我需要告诉它列数和行数(每列可能总是有8个元素),并用连续的数字填充特定的字体样式/矩形颜色。
我尝试为矩形/标签组合创建一个stackpanel UserControl,将样式传递给它,然后在网格中的特定行/列中添加32个UserControl。但我需要该网格的大小是动态的,所以我想在代码中需要一些for循环。
谢谢!
答案 0 :(得分:3)
我会从ItemsControl
您可以为其提供一组项目,它会根据您的需要呈现每个项目,并显示在您想要的任何面板中。
例如,你可能有类似这样的东西
<ItemsControl ItemsSource="{Binding MyCollection}">
<!-- This panel will be used to hold the items -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="8" Columns="8" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- Each item will be drawn using this template -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Text="{Binding }" Style="{StaticResource MyButtonStyle}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
UniformGrid的Rows
和Columns
属性是DependencyProperties,因此您可以将它们绑定到DataContext上的属性以使其动态化。
UniformGrid
的唯一问题是it only arranges items Horizontally。如果要垂直显示它们,可以创建custom UniformGrid,也可以切换到其他面板,例如WrapPanel
。如果您不熟悉WPF面板,我建议您阅读WPF Layouts - A Quick Visual Start。
ItemTemplate可以是任何东西。我个人会使用一个Button,因此您可以使用Click或Command行为来处理该事件,只需覆盖Button的模板即可查找。将触发器包含在那里也很容易。
如果您想要选择行为,我建议您从ItemsControl切换到ListBox,并以相同的方式覆盖该模板,但它听起来并不像您需要它,所以我认为ItemsControl更好:)
答案 1 :(得分:1)
我会尝试使用listview并将模板更改为您要用于元素的样式。
要限制行中的项目数量,您可以使用
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="3" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
这样你就可以连续获得3个元素,比如
123
456
要使3动态,您可以在代码隐藏/ viewmodel中将其数据绑定为某个值
动态创建listview中的元素,您可以将对象添加到列表/可观察集合中,然后通过
将它们添加到列表视图中listviewname.ItemSource=ListName;
或者你喜欢。它们将根据您告诉网格有多少列进行排列。添加32个项目(统一网格为4)导致
1 2 3 4
5 6 7 8
9 10 11 12
...
答案 2 :(得分:-1)
在您的页面上,您必须创建一个&#34; main&#34;元素,例如网格。 给它一个名字,以便我们可以通过代码访问它。在这里,我给它命名为 root
所以你会有像
这样的东西<Page
... >
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
x:Name="root">
</Grid>
</Page>
然后,在此页面的.cs文件中,您必须使用以下代码创建一个函数。您可以在MainPage()函数上调用此函数。
此循环将创建一个带有动态网格行的网格列
// Create a Grid and add it to a component of your page
Grid mainGrid = new Grid();
root.Children.Add(mainGrid);
for (int i = 0; i < 8; i++)
{
// I am creating a Grid with a TextBlock inside,
// it will have the same apperance as a Rectangle,
// but this way you can have a Text inside
Grid g = new Grid();
TextBlock tb = new TextBlock();
tb.Text = i.ToString();
g.Children.Add(tb);
// Here you set the Grid properties, such as border and alignment
// You can add other properties and events you need
g.BorderThickness = new Thickness(1);
g.BorderBrush = new SolidColorBrush(Colors.Black);
g.HorizontalAlignment = HorizontalAlignment.Stretch;
g.VerticalAlignment = VerticalAlignment.Stretch;
// Add the newly created Grid to the outer Grid
mainGrid.RowDefinitions.Add(new RowDefinition());
mainGrid.Children.Add(g);
// Set the row of the Grid.
Grid.SetRow(g, i);
}
我使用了Grid而不是Rectangle,因为Rectangles不能有Children。
使用与创建Rows时相同的逻辑,也很容易创建其他列。