是否可以将窗体中的表格用作矩阵?
本文关键字:表格 窗体 是否 | 更新日期: 2023-09-27 18:02:16
我试图创建一个简单的6X8单元格矩阵,用户可以单击单元格并将其打开或关闭,黑色或白色。我一直在尝试使用windows窗体控件,并查看了数据网格控件,但到目前为止,我还没有看到使用Winforms工具箱中的任何东西来创建矩阵的方法。
我创建了这个表,但是没有办法为每个单元格单独设置样式,或者为每个单元格使用onclick事件。这可能吗?如果不可能,有没有别的方法?
这是一个在运行时创建标签的解决方案。你需要一个面板来容纳你的"矩阵"和一个按钮,都有默认的名称。点击按钮将绘制一个棋盘,你可以通过点击每个单元格来翻转颜色。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
const int RowCount = 6;
const int ColumnCount = 8;
private void button1_Click(System.Object sender, System.EventArgs e)
{
for (int i = 0; i < RowCount; i++)
{
for (int j = 0; j < ColumnCount; j++)
{
Label lbl = new Label();
lbl.Size = new Size(20, 20);
lbl.Location = new Point(i * 20, j * 20);
lbl.BackColor = (i + j) % 2 == 0 ? Color.Black : Color.White;
lbl.Click += lbl_Click;
panel1.Controls.Add(lbl);
}
}
MessageBox.Show(CountCellsOfColor(Color.Black).ToString());
}
private int CountCellsOfColor(Color color)
{
int count = 0;
foreach (Label lbl in panel1.Controls.OfType<Label>())
{
if (lbl.BackColor == color) count += 1;
}
return count;
}
private void lbl_Click(object sender, System.EventArgs e)
{
Label lbl = (Label)sender;
Color color = lbl.BackColor;
if (color == System.Drawing.Color.Black)
{
color = System.Drawing.Color.White;
}
else
{
color = System.Drawing.Color.Black;
}
lbl.BackColor = color;
}
}
VB。. NET版本(原始版本,后来转换为c#,但决定保留,以防有人需要):
Option Strict On
Public Class Form1
Const RowCount As Integer = 6
Const ColumnCount As Integer = 8
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
For i = 0 To RowCount - 1
For j = 0 To ColumnCount - 1
Dim lbl As New Label
lbl.Size = New Size(20, 20)
lbl.Location = New Point(i * 20, j * 20)
lbl.BackColor = If((i + j) Mod 2 = 0, Color.Black, Color.White)
AddHandler lbl.Click, AddressOf lbl_Click
Panel1.Controls.Add(lbl)
Next
Next
MessageBox.Show(CountCellsOfColor(Color.Black))
End Sub
Private Function CountCellsOfColor(color As Color) As Integer
Dim count As Integer = 0
For Each lbl In Panel1.Controls.OfType(Of Label)()
If lbl.BackColor = color Then count += 1
Next
Return count
End Function
Private Sub lbl_Click(sender As Object, e As System.EventArgs)
Dim lbl As Label = CType(sender, Label)
Dim color As Color = lbl.BackColor
If color = Drawing.Color.Black Then
color = Drawing.Color.White
Else
color = Drawing.Color.Black
End If
lbl.BackColor = color
End Sub
End Class
我认为你可以在WinForms中使用DataGridView控件。您可以设置所需的列数和行数。例如,对于列
m_Grid.ColumnCount = 5;
和
行m_Grid.Rows.Add();
你可以处理CellClick, CellDoumleClick或其他事件,并使用参数DataGridViewCellEventArgs和它的字段。例如
m_Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Style.BackColor = Color.Red;
最好在运行时使用一组标签:
List<Label> lables=new List<Label>();
var a = new Label();
labels.Add(a);
//... set positions and sizes
a.AutoSize=False;
this.Controls.Add(a);
有了这个,以后你可以索引标签数组中的每个标签,以匹配你的行/col位置。
这是我的WPF方法:
<Window x:Class="WpfApplication4.Window13"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window13" Height="300" Width="300">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="8" Columns="6" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<Storyboard x:Key="ToBlack" TargetName="RctFill" Duration="00:00:00.5">
<ColorAnimation From="White" To="Black" Duration="00:00:00.5" Storyboard.TargetProperty="Color"/>
</Storyboard>
<Storyboard x:Key="ToWhite" TargetName="RctFill" Duration="00:00:00.5">
<ColorAnimation From="Black" To="White" Duration="00:00:00.5" Storyboard.TargetProperty="Color"/>
</Storyboard>
</DataTemplate.Resources>
<Button Command="{Binding ToggleCommand}">
<Button.Template>
<ControlTemplate>
<Rectangle Stroke="Black" StrokeThickness="1" x:Name="Rct">
<Rectangle.Fill>
<SolidColorBrush Color="White" x:Name="RctFill"/>
</Rectangle.Fill>
</Rectangle>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding State}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource ToBlack}"/>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource ToWhite}"/>
</DataTrigger.ExitActions>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
背后的代码:
using System;
using System.Linq;
using System.Windows;
using System.ComponentModel;
namespace WpfApplication4
{
public partial class Window13 : Window
{
public Window13()
{
var rnd = new Random();
InitializeComponent();
DataContext = Enumerable.Range(0, 48).Select(x => new Square() {State = rnd.Next(0,5) > 3});
}
}
public class Square:INotifyPropertyChanged
{
private bool _state;
public bool State
{
get { return _state; }
set
{
_state = value;
NotifyPropertyChanged("State");
}
}
private DelegateCommand _toggleCommand;
public DelegateCommand ToggleCommand
{
get { return _toggleCommand ?? (_toggleCommand = new DelegateCommand(x => State = !State)); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
我使用的是WPFTutorial中的DelegateCommand。净
只是复制和粘贴我的代码在File -> New Project -> WPF Application
和看到自己的结果。您还需要我链接到的DelegateCommand
定义。
从黑色到白色的过渡是动画的,你也可以扩展我的例子来动画其他属性,在每个单元格中放置任何你想要的UI。此外,您将意识到这是完全独立于分辨率的,并且调整窗口的大小也会调整UniformGrid
的大小,因此也会调整所有网格单元格的大小。
如果你需要把它放在一个winforms应用程序中,你需要使用ElementHost