Question

I have a task of programming a simple program-demonstration of the Lee Algorithm for pathfinding in a maze. I want to make it somewhat graphically interactive: create a 2D table with a variable amount of rows and columns, which's cells can be clicked (and the position of the clicked cell should be able to be tracked). This is because I want to let the user draw the maze obstacles, set the start point etc. What would be the best graphical component that could help me do this and how can I interact with its' cells?

Was it helpful?

Solution

Following on from your comment I would say that WPF is a more natural candidate for this task because it has been designed to do custom layout stuff. Here is a code example I've put together using an items control with a uniform grid that displays a grid of cells - clicking on a cell selects it, clicking again deselects it.

This isn't great WPF, but it might give you some ideas and get you started.

Application:

Application example image

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>

Code Behind (your MainWindow.xaml.cs code):

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

Happy coding!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top