-1

EDIT: I tried

Background.SetValue(Grid.RowProperty, 1)

and

Border.Background.SetValue(Grid.RowProperty, 1)

But got an error saying "Cannot set a property on object '#FFFFFFFFF' because it is in a read-only state."


I'm trying to make a random maze generator in WPF. So far I've made a startpage and a "Start" button, where when you click on the start button it leads you to the maze, where I want it to start generating itself.

https://i.stack.imgur.com/lfCQN.png

I've watched tutorials etc about, how it's supposed to be set up, and the whole theory behind it.

Right now I'm kind of stuck with a problem. I want the red square to move either to the field to the right or below it, and then color the previous field another color, so that the red square is the cell generating the maze, and the previous ones are the maze itself. But I can't seem to get permission to change the position of the red square in the programming code at all since it's read-only. But I need that cause I want to use loops etc.

    <Grid>
    <Rectangle Fill="Black" HorizontalAlignment="Left" Height="356" Margin="10,10,0,0" Stroke="Black" VerticalAlignment="Top" Width="772"/>
    <Button x:Name="Button1" Content="Start" HorizontalAlignment="Left" Margin="357,380,0,0" VerticalAlignment="Top" Width="74" Click="Button1_Click_1"/>
    <TextBlock x:Name="Title1" HorizontalAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Top" Height="70" Width="654" Margin="70,71,68,0" Foreground="White" FontSize="60" FontFamily="Impact" FrameworkElement.FlowDirection="LeftToRight" TextAlignment="Center">
        <TextBlock.Triggers>
            <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="Title1" Storyboard.TargetProperty="(FrameworkElement.Height)" To="0.0" Duration="00:00:02" DecelerationRatio="0" AutoReverse="True" BeginTime="00:00:02" RepeatBehavior="Forever" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </TextBlock.Triggers><Run Text="Random Maze Generator">
            <Run.Background>
                <ImageBrush/>
            </Run.Background>
        </Run></TextBlock>
    <TextBlock x:Name="Title2" HorizontalAlignment="Left" Margin="246,254,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="54" Width="298" Foreground="White" FontSize="30" Text="Press Start to continue"/>
    <Grid Name="GridLines" ShowGridLines="False" Width="772" Height="356" Margin="10,10,10,53">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Border Name="Cell" Grid.Row="0" Grid.Column="0" Background="Red" Opacity="0" Visibility="Visible"/>
        <StackPanel Name="Stack"  Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left"></StackPanel>
    </Grid>
</Grid>

    public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    double columns = 16;
    int rows = 8;
    double square_width;
    double square_height;
    double square_area;
    int current_cell;
    int visited_cell;

    private void Button1_Click_1(object sender, RoutedEventArgs e) //After the Start button is pressed
    {
        Title1.Text = String.Empty; //Hide text for Title1
        Title2.Text = String.Empty; //Hide text for Title2

        GridLines.ShowGridLines = true; //Changes the value for GridLines from false to true
        Cell.Opacity = 100; //Changes the cell opacity from 0% to 100%

    }
}

}

The red square is located in Border.Grid.Row="0"and Border.Grid.Column="0" in Xaml, but I have no idea how to access either. I thought for a long time that it was Grid.RowProperty or Grid.ColumnProperty I had to mess with but those are read-only.

I'm fairly new to programming, and REALLY new to WPF so this might be a dumb question, not trying to trigger anyone.

Thank you for your time.

  • Just a side note: if you want to hide an element (like hiding the TextBlocks), you are better to set the Visibility property, like `Title1.Visibility = Visibility.Collapsed;` – mami Dec 07 '18 at 09:23
  • Also note that Opacity is a double value in the range 0..1, not a percentage. – Clemens Dec 07 '18 at 09:26
  • Yeah sorry about that. I have been editing videos and 3d modelling for a long time so I kinda assumed the value, but it still seemed to work. – TheOldHerbert Dec 07 '18 at 09:33
  • instead of `Border.Background.SetValue(Grid.RowProperty, 1)` use `Cell.SetValue(Grid.RowProperty, 1)` – ASh Dec 07 '18 at 10:07
  • Ouu yes!! That worked! Thanks a lot. I basically just made this account so I don't know if I can give you any points for you answer. If you know how then just let me know. – TheOldHerbert Dec 07 '18 at 10:21
  • @TheOldHerbert, you should have an option to close this question as a duplicate which I linked – ASh Dec 07 '18 at 11:01

2 Answers2

0

I think you'd do better to use a canvas rather than a grid. You can then easily animate your red square from any position to another smoothly by animating canvas.left and canvas.top.

You can overlay controls on top of one another so the canvas the piece is "on" can be on top of an itemscontrol. Give that a wrappanel as an itemspanel and it'll wrap around whatever you template the contents into from one row to another. Bind a collection of cellVM ( a viewmodel per cell ) to the itemssource of your itemscontrol. Then use an itemtemplate to turn each into a cell of your maze. This could be as simple as a rectangle which is one colour for closed and another for open. That could have a border for the outline of each cell or you could overlay with an image which is a grid. You could alternatively build an image using writeablebitmap for your maze background but the itemscontrol templating is relatively easy if your requirement is simple.

Andy
  • 11,864
  • 2
  • 17
  • 20
0

Basically your question is "How to set an attached property in code behind?". An attached property is generally a property that is defined by a control that gives it some role but usually this properties are set on controls of other types. In your case Column and Row properties are used by the grid for the layouting of child elements.

Setting this properties is fairly simple. You just all the associated setter function like this:

Grid.SetColumn(Cell, 1);

However as Andy mentioned using Grid is not the best option.

Dmitry
  • 2,033
  • 1
  • 22
  • 31