【问题标题】:WPF: How to dynamically create a grid with x rows and y columns with consecutive numbersWPF:如何动态创建具有连续数字的 x 行和 y 列的网格
【发布时间】:2015-11-30 22:58:27
【问题描述】:

我对 wpf 和 c# 完全陌生,如果这是一个非常琐碎的问题,请原谅。我正在尝试创建一个相当简单的控件。

这个网格总是有连续的数字,前面有一个彩色矩形。单击灰色矩形将更改其颜色,并将文本设置为粗体(稍后我将处理这些触发器)。

现在,我只需要弄清楚如何动态地创建这个控件。程序启动时,需要一次创建这个控件,然后大小不会改变。我需要告诉它列数和行数(每列可能总是有 8 个元素),并让它填充具有特定字体样式/矩形颜色的连续数字。

我尝试为矩形/标签组合创建一个堆栈面板用户控件,将样式传递给它,然后在网格的特定行/列中添加 32 个这些用户控件。但是我需要该网格的大小是动态的,所以我认为代码中需要一些 for 循环。

谢谢!

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    我会从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 的 RowsColumns 属性是 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 更好:)

    【讨论】:

      【解决方案2】:

      我会尝试使用列表视图并将模板更改为您想要用于元素的样式。

      要限制您可以使用的一行中的项目数

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

      这样你总是会连续获得 3 个元素,比如

      123

      456

      要使 3 动态化,您可以将其数据绑定到代码隐藏/视图模型中的某个值

      要在列表视图中动态创建元素,您可以将对象添加到列表/可观察集合中,然后通过

      将这些对象添加到列表视图中
      listviewname.ItemSource=ListName;
      

      或者随你喜欢。它们将根据您告诉网格有多少列进行排列。添加 32 个项目(统一网格为 4)导致

      1 2 3 4

      5 6 7 8

      9 10 11 12

      ...

      【讨论】:

        【解决方案3】:

        您必须在您的页面上创建一个“主”元素,例如网格。 给它一个名字,以便我们可以通过代码访问它。这里我给它起名为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,因为 Rectangle 不能有孩子。

        创建其他列也必须很容易,使用与创建行相同的逻辑。

        【讨论】:

        • 您能帮我弄清楚该代码的放置位置吗?对不起,如果这是一个微不足道的问题,但我真的是这方面的新手。我没有 ViewModel。如果我将该代码放在自定义控件的代码隐藏 (xaml.cs) 中,它会抱怨“root”不存在。
        • @wpfNewbie 用其他信息编辑了我的答案
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-14
        • 1970-01-01
        • 2020-02-13
        相关资源
        最近更新 更多