简体   繁体   English

WPF:如何动态创建具有连续数字的 x 行和 y 列的网格

[英]WPF: How to dynamically create a grid with x rows and y columns with consecutive numbers

I am completely new to wpf and c#, so excuse if this is super trivial question.我对 wpf 和 c# 完全陌生,如果这是一个非常琐碎的问题,请原谅。 I am trying to create a fairly simple control.我正在尝试创建一个相当简单的控件。

网格

This grid will always have consecutive numbers, with a color rectangle in front of it.这个网格总是有连续的数字,前面有一个彩色矩形。 Clicking on the gray rectangle will change its color, and set the text to bold (I will deal with these triggers later).单击灰色矩形将更改其颜色,并将文本设置为粗体(稍后我将处理这些触发器)。

For now, I just need to figure out how to create this control dynamically.现在,我只需要弄清楚如何动态地创建这个控件。 When the program starts, it needs to one time create this control, and then the size won't change.程序启动时,需要一次创建这个控件,然后大小就不会改变。 I need to tell it the number of columns and rows (each column will probably always have 8 elements), and have it populate with consecutive numbers with specific font style/rectangle color.我需要告诉它列数和行数(每列可能总是有 8 个元素),并让它填充具有特定字体样式/矩形颜色的连续数字。

I was experimented with creating a stackpanel UserControl for rectangle/label combo, passing the style to it, and then adding 32 of these UserControls in specific row/column in a grid.我尝试为矩形/标签组合创建一个堆栈面板用户控件,将样式传递给它,然后在网格的特定行/列中添加 32 个这些用户控件。 But I would need the size of that grid to be dynamic, so I need some for loop in the code I think.但是我需要该网格的大小是动态的,所以我认为代码中需要一些 for 循环。

Thanks!谢谢!

I would start with an ItemsControl我将从ItemsControl开始

You can give it a collection of items, and it will render each item however you want, displayed in any panel you want.你可以给它一个项目的集合,它会以你想要的方式呈现每个项目,显示在你想要的任何面板中。

For example, you might have something like this例如,您可能有这样的事情

<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>

The Rows and Columns property of the UniformGrid are DependencyProperties, so you could bind them to properties on the DataContext to make them dynamic. UniformGrid 的RowsColumns属性是 DependencyProperties,因此您可以将它们绑定到 DataContext 上的属性以使它们动态化。

The only problem with a UniformGrid is it only arranges items Horizontally . UniformGrid的唯一问题是它只能水平排列项目 If you want to display them Vertically, you can either create a custom UniformGrid , or switch to a different panel such as a WrapPanel .如果要垂直显示它们,可以创建自定义 UniformGrid或切换到不同的面板,例如WrapPanel If you are new to WPF Panels, I would recommend reading through WPF Layouts - A Quick Visual Start .如果您是 WPF 面板的新手,我建议您通读WPF 布局 - 快速可视化开始

The ItemTemplate can be anything. ItemTemplate 可以是任何东西。 Personally I would use a Button so you have the Click or Command behavior to handle that event, and just overwrite the Button's Template to look however you want.就我个人而言,我会使用一个 Button,这样您就可以使用 Click 或 Command 行为来处理该事件,并且只需覆盖 Button 的模板以显示您想要的外观。 It is an easy task to include your Triggers in there too.在其中包含您的触发器也是一项简单的任务。

And if you wanted selection behavior, I would recommend switching from an ItemsControl to a ListBox, and overwriting that Template the same way, however it doesn't sound like you need it though, so I think an ItemsControl is better :)如果您想要选择行为,我建议从 ItemsControl 切换到 ListBox,并以相同的方式覆盖该模板,但听起来您并不需要它,所以我认为 ItemsControl 更好:)

On your page you must create a "main" element, for example a Grid.在您的页面上,您必须创建一个“主”元素,例如网格。 Give it a name, so that we can access it by code.给它一个名字,以便我们可以通过代码访问它。 Here I gave it the name of root这里我给它起了root的名字

So you will have something like所以你会有类似的东西

<Page
    ... >

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
          x:Name="root">

    </Grid>
</Page>

Then, on the .cs file of this page you must create a function with the code below.然后,在此页面的 .cs 文件中,您必须使用以下代码创建一个函数。 You can call this function on the MainPage() function.您可以在 MainPage() 函数上调用此函数。

This loop will create one Grid column with dynamic Grid rows此循环将创建一个具有动态 Grid 行的 Grid 列

// 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);
}

I used a Grid instead of a Rectangle since Rectangles can't have Children.我使用了 Grid 而不是 Rectangle,因为 Rectangles 不能有孩子。

It must be easy to create the other columns as well, using the same logic that I used to create the Rows.使用与创建行相同的逻辑创建其他列也必须很容易。

I would try using a listview and change the template to the style you want to use for your elements.我会尝试使用列表视图并将模板更改为您想要用于元素的样式。

To limit the number of items in a row you can use要限制一行中的项目数,您可以使用

  <ListView.ItemsPanel>
    <ItemsPanelTemplate>
        <UniformGrid Columns="3" />
    </ItemsPanelTemplate>
  </ListView.ItemsPanel>

That way you would always get 3 elements in a row, like这样你总是会连续获得 3 个元素,比如

123 123

456 456

To make the 3 dynamic you can databind it to some value in your codebehind / viewmodel要使 3 动态化,您可以将其数据绑定到代码隐藏/视图模型中的某个值

to dynamically create the elements within the listview you can add objects to a list/observable collection and then add those to the listview via要在列表视图中动态创建元素,您可以将对象添加到列表/可观察集合中,然后通过

listviewname.ItemSource=ListName;

Or however you like.或者随你喜欢。 They will get arranged according to how many columns you tell the grid to have.它们将根据您告诉网格有多少列进行排列。 Adding 32 items (with uniform grid of 4) leads to添加 32 个项目(具有 4 个统一网格)导致

1 2 3 4 1 2 3 4

5 6 7 8 5 6 7 8

9 10 11 12 9 10 11 12

... ...

The solution to me was pretty like the ones above, but I had to bind the ItemsSource in the back code.对我来说解决方案和上面的很像,但是我必须在后面的代码中绑定 ItemsSource。

<!-- This panel will be used to hold the items -->
<ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
        <StackPanel/>
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

<!-- Each item will be drawn using this template -->
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <!--Here is the big deal I think. Desing your template according to what you need. In this case, a grid with 1 default row and column will work--> 
        <Grid>
            <!--Reading object property called "Exchange" and setting its value into a text block-->
            <TextBlock
                Margin="10, 10, 10, 40" FontSize="16" 
                HorizontalAlignment="Center"
                VerticalAlignment="Center" Foreground="GreenYellow" Text="{Binding Exchange}" />    
        </Grid>
    </DataTemplate>
</ItemsControl.ItemTemplate>

Then in the page.cs I did the binding right in the constructor.然后在 page.cs 中,我在构造函数中进行了绑定。 But you can bind anytime suits you但你可以随时绑定适合你

List<Bot> Bots = new()
{
    new Bot
    {
        Exchange = "Binance"
    },
    new Bot
    {
        Exchange = "Kukoin"
    }
};

ItemsControlName.ItemsSource = Bots; // I HAD to bind here. Could not make it work another way.

In my example, I have used a list of a simple class called Bot, with one single property called Exchange.在我的示例中,我使用了一个名为 Bot 的简单类的列表,其中包含一个名为 Exchange 的属性。 Like this像这样

public class Bot
{
   public string Exchange { get; set; }
}

Then I got it:然后我明白了: 在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM