C#Windows窗体Lee算法图形组件
我的任务是编写一个简单的程序演示Lee算法在迷宫中的寻路。我想让它有点图形化的交互性:创建一个具有可变行数和列数的二维表,可以单击其中的单元格(并且可以跟踪单击单元格的位置)。这是因为我想让用户画迷宫障碍物,设置起点等。什么是最好的图形组件可以帮助我做到这一点,我如何与它的“细胞”交互 根据您的评论,我想说WPF是这个任务的一个更自然的候选者,因为它被设计用于定制布局。下面是一个代码示例,我使用了一个带有统一网格的items控件,该网格显示一个单元格网格-单击单元格将选中它,再次单击将取消选中它 这不是很好的WPF,但它可能会给你一些想法,让你开始 应用程序:C#Windows窗体Lee算法图形组件,c#,winforms,interactive,graphic,C#,Winforms,Interactive,Graphic,我的任务是编写一个简单的程序演示Lee算法在迷宫中的寻路。我想让它有点图形化的交互性:创建一个具有可变行数和列数的二维表,可以单击其中的单元格(并且可以跟踪单击单元格的位置)。这是因为我想让用户画迷宫障碍物,设置起点等。什么是最好的图形组件可以帮助我做到这一点,我如何与它的“细胞”交互 根据您的评论,我想说WPF是这个任务的一个更自然的候选者,因为它被设计用于定制布局。下面是一个代码示例,我使用了一个带有统一网格的items控件,该网格显示一个单元格网格-单击单元格将选中它,再次单击将取消选中它
<Window x:Class="LeeAlgorithm.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="380" Width="350">
<Grid>
<ItemsControl ItemsSource="{Binding Cells}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="5" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="18"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</DataTemplate.Resources>
<Grid Width="30" Height="30" Margin="2">
<DockPanel ZIndex="9999">
<!-- This is a hack to capture the mouse click in the area of the item -->
<Rectangle
Fill="Transparent"
DockPanel.Dock="Top"
MouseDown="UIElement_OnMouseDown"
Tag="{Binding}" />
</DockPanel>
<Grid>
<Rectangle Fill="{Binding Path=Color}" Stroke="Red" StrokeDashArray="1 2" />
<TextBlock Margin="3,3,3,0" Text="{Binding Path=CellNumber}"/>
</Grid>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
namespace LeeAlgorithm
{
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
this.Cells = new ObservableCollection<Cell>();
for (int i = 0; i != 50; ++i)
{
this.Cells.Add(new Cell { CellNumber = i });
}
InitializeComponent();
DataContext = this;
}
public ObservableCollection<Cell> Cells { get; private set; }
private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
{
var cell = (Cell)((Rectangle)sender).Tag;
if (!cell.IsSelected)
{
cell.Color = new SolidColorBrush(Colors.HotPink);
cell.IsSelected = true;
}
else
{
cell.Color = new SolidColorBrush(Colors.Silver);
cell.IsSelected = false;
}
}
}
public class Cell : INotifyPropertyChanged
{
private int cellNumber;
private SolidColorBrush color = new SolidColorBrush(Colors.Silver);
public event PropertyChangedEventHandler PropertyChanged;
public int CellNumber
{
get
{
return this.cellNumber;
}
set
{
if (value == this.cellNumber)
{
return;
}
this.cellNumber = value;
this.OnPropertyChanged("CellNumber");
}
}
public SolidColorBrush Color
{
get
{
return this.color;
}
set
{
if (Equals(value, this.color))
{
return;
}
this.color = value;
this.OnPropertyChanged("Color");
}
}
public bool IsSelected { get; set; }
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
XAML:
<Window x:Class="LeeAlgorithm.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="380" Width="350">
<Grid>
<ItemsControl ItemsSource="{Binding Cells}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="5" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="18"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</DataTemplate.Resources>
<Grid Width="30" Height="30" Margin="2">
<DockPanel ZIndex="9999">
<!-- This is a hack to capture the mouse click in the area of the item -->
<Rectangle
Fill="Transparent"
DockPanel.Dock="Top"
MouseDown="UIElement_OnMouseDown"
Tag="{Binding}" />
</DockPanel>
<Grid>
<Rectangle Fill="{Binding Path=Color}" Stroke="Red" StrokeDashArray="1 2" />
<TextBlock Margin="3,3,3,0" Text="{Binding Path=CellNumber}"/>
</Grid>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
namespace LeeAlgorithm
{
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
this.Cells = new ObservableCollection<Cell>();
for (int i = 0; i != 50; ++i)
{
this.Cells.Add(new Cell { CellNumber = i });
}
InitializeComponent();
DataContext = this;
}
public ObservableCollection<Cell> Cells { get; private set; }
private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
{
var cell = (Cell)((Rectangle)sender).Tag;
if (!cell.IsSelected)
{
cell.Color = new SolidColorBrush(Colors.HotPink);
cell.IsSelected = true;
}
else
{
cell.Color = new SolidColorBrush(Colors.Silver);
cell.IsSelected = false;
}
}
}
public class Cell : INotifyPropertyChanged
{
private int cellNumber;
private SolidColorBrush color = new SolidColorBrush(Colors.Silver);
public event PropertyChangedEventHandler PropertyChanged;
public int CellNumber
{
get
{
return this.cellNumber;
}
set
{
if (value == this.cellNumber)
{
return;
}
this.cellNumber = value;
this.OnPropertyChanged("CellNumber");
}
}
public SolidColorBrush Color
{
get
{
return this.color;
}
set
{
if (Equals(value, this.color))
{
return;
}
this.color = value;
this.OnPropertyChanged("Color");
}
}
public bool IsSelected { get; set; }
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
代码隐藏(MainWindow.xaml.cs代码):
<Window x:Class="LeeAlgorithm.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="380" Width="350">
<Grid>
<ItemsControl ItemsSource="{Binding Cells}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="5" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="18"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</DataTemplate.Resources>
<Grid Width="30" Height="30" Margin="2">
<DockPanel ZIndex="9999">
<!-- This is a hack to capture the mouse click in the area of the item -->
<Rectangle
Fill="Transparent"
DockPanel.Dock="Top"
MouseDown="UIElement_OnMouseDown"
Tag="{Binding}" />
</DockPanel>
<Grid>
<Rectangle Fill="{Binding Path=Color}" Stroke="Red" StrokeDashArray="1 2" />
<TextBlock Margin="3,3,3,0" Text="{Binding Path=CellNumber}"/>
</Grid>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
namespace LeeAlgorithm
{
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
this.Cells = new ObservableCollection<Cell>();
for (int i = 0; i != 50; ++i)
{
this.Cells.Add(new Cell { CellNumber = i });
}
InitializeComponent();
DataContext = this;
}
public ObservableCollection<Cell> Cells { get; private set; }
private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
{
var cell = (Cell)((Rectangle)sender).Tag;
if (!cell.IsSelected)
{
cell.Color = new SolidColorBrush(Colors.HotPink);
cell.IsSelected = true;
}
else
{
cell.Color = new SolidColorBrush(Colors.Silver);
cell.IsSelected = false;
}
}
}
public class Cell : INotifyPropertyChanged
{
private int cellNumber;
private SolidColorBrush color = new SolidColorBrush(Colors.Silver);
public event PropertyChangedEventHandler PropertyChanged;
public int CellNumber
{
get
{
return this.cellNumber;
}
set
{
if (value == this.cellNumber)
{
return;
}
this.cellNumber = value;
this.OnPropertyChanged("CellNumber");
}
}
public SolidColorBrush Color
{
get
{
return this.color;
}
set
{
if (Equals(value, this.color))
{
return;
}
this.color = value;
this.OnPropertyChanged("Color");
}
}
public bool IsSelected { get; set; }
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
namespace算法
{
使用System.Collections.ObjectModel;
使用系统组件模型;
使用System.Windows;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Shapes;
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
公共主窗口()
{
this.Cells=新的可观察集合();
对于(int i=0;i!=50;++i)
{
Add(新单元格{CellNumber=i});
}
初始化组件();
DataContext=this;
}
公共可观察集合单元格{get;private set;}
私有void UIElement_OnMouseDown(对象发送器,鼠标按钮ventargs e)
{
var cell=(cell)((矩形)sender.Tag;
如果(!cell.IsSelected)
{
cell.Color=新的SolidColorBrush(Colors.HotPink);
cell.IsSelected=true;
}
其他的
{
cell.Color=新的SolidColorBrush(Colors.Silver);
cell.IsSelected=false;
}
}
}
公共类单元格:INotifyPropertyChanged
{
私人国际电话号码;
私有SolidColorBrush颜色=新的SolidColorBrush(Colors.Silver);
公共事件属性更改事件处理程序属性更改;
公共国际电话号码
{
得到
{
返回此.cellNumber;
}
设置
{
if(值==此.cellNumber)
{
返回;
}
this.cellNumber=值;
此。OnPropertyChanged(“手机号码”);
}
}
公共色刷颜色
{
得到
{
返回此.color;
}
设置
{
if(等于(值,此颜色))
{
返回;
}
这个颜色=值;
此。OnPropertyChanged(“颜色”);
}
}
公共布尔值被选为{get;set;}
受保护的虚拟void OnPropertyChanged(字符串propertyName)
{
var handler=PropertyChanged;
if(处理程序!=null)
{
处理程序(这是新的PropertyChangedEventArgs(propertyName));
}
}
}
}
快乐编码 您可以使用WPF吗?还是仅限于winforms?在WPF中,可能有一些很好的方法可以做到这一点。实际上,我对WPF的经验很少,但如果能听到一些关于这一点的想法,那就太好了