-2

I want to draw a samurai sudoku grid on my C# WPF project. this is the example of samurai sudoku

https://www.samurai-sudoku.com/sudoku3.gif

for each TextBox within the grid, I want to load it with dynamic value from the txt file.

txt file : "23987239847239847" (in total 405 integers)

I already have the normal sudoku grid working

code:

    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="{Binding Dimension}" Columns="{Binding Dimension}" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBox HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Text="{Binding Value, Mode=TwoWay}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

What are the most efficient ways to draw a grid that looks like a samurai suoku grid?

  • 1
    "Is there a way to draw the grid?" Perhaps you need to rephrase that question because, if you are to be taken literally, then the answer is **yes, there is a way**. What do you actually need to know? What did you try? – Wyck Jun 11 '21 at 18:59
  • 1
    One of the possible options. Make UniformGrid 21x21. In the cells set Border with the required background and borders. Put TextBox inside Border. And it's better to use not a TextBox, but a ComboBox with a list of valid values. – EldHasp Jun 11 '21 at 19:02
  • @EldHasp, Why 21x21? because you have 81x5(405) Textboxes/Comboxes right? – Jonas Newejs Jun 11 '21 at 19:08
  • UniformGrid automatically splits the entire field into equal sized columns and rows. Child elements are automatically placed sequentially in all cells. For the Grid, you have to specify a collection of rows and columns. And for each daughter element, set the coordinate in which cell to place it. – EldHasp Jun 11 '21 at 19:13
  • For this, the total number of cells in height and width is 21. How much, then, to split? In empty cells (between Sudoku blocks) set the output of transparent Border. – EldHasp Jun 11 '21 at 19:15
  • You are using ItemsControl. In those places where there should be empty space, write null. – EldHasp Jun 11 '21 at 19:18
  • @EldHasp for the empty cells, should I make a validator to skip it and not bind it to a value? another question: does xaml also work with conditions for specific cells to skip? – Jonas Newejs Jun 11 '21 at 19:20
  • If you do not need to set borders of different thickness, then of course a regular TextBox will be enough for a cell. – EldHasp Jun 11 '21 at 19:20
  • " for the empty cells, should I make a validator to skip it and not bind it to a value?" - Set a style trigger that compares the current context to null. Add a setter to the trigger with Opacity = 0. – EldHasp Jun 11 '21 at 19:31
  • @EldHasp the UniformGrid Rows and Colums should be both 21? and Datatemplate I need to add border and inside a border a textbox? – Jonas Newejs Jun 11 '21 at 19:38

1 Answers1

0

Example for demonstration. It is not as difficult as in the picture in the question. But it will not be a problem for you to supplement it.

public class SudokuCell
{
    public Thickness Border { get; }
    public int Value { get; set; }

    public int Row { get; }
    public int Column { get; }

    public SudokuCell(int row, int column, Thickness border)
    {
        Row = row;
        Column = column;
        Border = border;
    }

    public SudokuCell(int row, int column, Thickness border, int value)
        : this(row, column, border)
    {
        Value = value;
    }
}
public class SudokuViewModel
{
    public ObservableCollection<SudokuCell> Cells { get; }
        = new ObservableCollection<SudokuCell>();

    public IEnumerable<int> ValidValues { get; } = Enumerable.Range(1, 9);

    private readonly SudokuCell[,] cellsArray;

    private static readonly Random random = new Random();
    public SudokuViewModel()
    {
        cellsArray = new SudokuCell[9, 9];
        for (int row = 0; row < 9; row++)
        {
            for (int column = 0; column < 9; column++)
            {
                if ((row / 3 + column / 3) % 2 == 1)
                    continue;

                double left = 0.5;
                if (column % 3 == 0)
                    left = 3;

                double top = 0.5;
                if (row % 3 == 0)
                    top = 3;

                double right = 0.5;
                if (column % 3 == 2)
                    right = 3;

                double bottom = 0.5;
                if (row % 3 == 2)
                    bottom = 3;

                int value = 0;
                if (random.Next(5) < 2)
                    value = random.Next(9) + 1;

                cellsArray[row, column] = new SudokuCell(
                    row,
                    column,
                    new Thickness(left, top, right, bottom),
                    value);
            }
        }

        foreach (var cell in cellsArray)
        {
            Cells.Add(cell);
        }
    }
}
    <Window.Resources>
        <local:SudokuViewModel x:Key="viewModel"/>
        <ItemsPanelTemplate x:Key="Sudoku.Panel">
            <UniformGrid Columns="9" Rows="9"/>
        </ItemsPanelTemplate>
        <DataTemplate x:Key="Sudoku.CellTemplate" DataType="{x:Type local:SudokuCell}">
            <Border BorderBrush="SkyBlue" BorderThickness="{Binding Border}"
                    Background="{Binding Background, ElementName=comboBox}">
                <Border.Style>
                    <Style>
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding}" Value="{x:Null}">
                                <Setter Property="Border.Opacity" Value="0"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
                <ComboBox x:Name="comboBox" ItemsSource="{Binding ValidValues, Source={StaticResource viewModel}}"
                          SelectedItem="{Binding Value}"
                          FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center"
                          BorderThickness="0"/>
                </Border>
        </DataTemplate>
    </Window.Resources>
    <ItemsControl ItemsSource="{Binding Cells, Source={StaticResource viewModel}}"
                  ItemTemplate="{DynamicResource Sudoku.CellTemplate}"
                  ItemsPanel="{DynamicResource Sudoku.Panel}"/>

enter image description here

EldHasp
  • 6,079
  • 2
  • 9
  • 24