How to select child in grid by column and row number - c#

How can I locate an ui-element by Its location (row and column)?

UIElement FindByCell1(Grid g, int row, int col)
{
var childs = g.Children.Cast<UIElement>()
return childs.Where(x => Grid.GetRow(x) == row && Grid.GetColumn(x) == col).FirstOrDefault();
}
If there may be some elements in the same cell:
IEnumerable<UIElement> FindByCell(Grid g, int row, int col)
{
var childs = g.Children.Cast<UIElement>()
return childs.Where(x => Grid.GetRow(x) == row && Grid.GetColumn(x) == col);
}
In your case, This way - working directly with the elements in the UI - its very very not recommended, and its the extreme opposite of MVVM.

Great answer. My implementation (Generating array of Buttons in code then want indexed array thereof):
Button[,] Buttons = new Button[8, endTimePlus1 - startTime];
var buttons = controlGrid.Children.Cast<Button>();
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < endTimePlus1 - startTime; j++)
{
Buttons[i,j] = buttons.Where(x => Grid.GetRow(x) == j && Grid.GetColumn(x) == i).FirstOrDefault();
}
}

Related

C# method freezes entire program

I've written the following method in C# for a small Forms program I'm working on, but whenever I try to run this method the entire program freezes.
There are no errors and I've tried to do for (int n = 0; n<8; n++) instead of while(true), but that didn't seem to change anything...
Any ideas?
Thanks in advance!
public bool legalMove(int y, int x)
{
// Check if the cell is occupied
if (grid[x, y] != 0)
return false;
// Check if there's an opponents circle somewhere around it
for (int i = -1; i<=1; i++)
for (int j = -1; i<=1; j++)
{
if (i == 0 && j == 0)
continue;
int row = x + i;
int col = y + j;
if (row >= 0 && row < 8 && col >= 0 && col < 8 && grid[col,row] == -turn)
{
// Now we know that there's an opponents circle somewhere around this space, we now check if it can be captured
while(true)
{
row += i;
col += j;
if (row < 0 || row > 7 || col < 0 || col > 7 || grid[row, col] == 0)
return false; // Outside of the board or an empty space
else if (grid[row, col] == turn)
return true; // No empty spaces between our cell and another cell of ours
}
}
}
return false; // No cell found around ours
}
Here's the problem: for (int j = -1; i<=1; j++). Should be j<=1 instead of i<=1.

Need advice on optimizing warehouse layout

I'm currently working for a distribution center with ~500 shelves with items for sale and ready to be shipped out to customers. I have decided to create a ranking for each aisle, where the best selling products will be stored at the front and the worst selling products will be stored at the back. I assumed that this would automatically improve efficience in my warehouse. However, after implementing this (see here). After using BFS to simulate a warehouse worker's route it's turned out that this new layout is actually taking more steps for a worker to complete than a regular non-optimized layout..
This is my code for BFS, however I think my problem lies in the way I decide where high demand items go, not in my BFS.
List<String> findPathBFS(magazijnObject[,] grid, bool[,] vis,
string start, string goal)
{
List<string> path = new List<string>();
// Stores indices of the matrix cells
Queue<pair> q = new Queue<pair>();
int row = 0; int col = 0;
// Mark the starting cell as visited
// and push it into the queue
for (int x = 0; x < grid.GetLength(0); x++)
for (int y = 0; y < grid.GetLength(1); y++)
{
if (grid[x, y].Locatie == start)
{
row = x; col = y;
x = grid.GetLength(0); y = grid.GetLength(1);
break;
}
}
q.Enqueue(new pair(row, col, null));
vis[row, col] = true;
// Iterate while the queue
// is not empty
while (q.Count != 0)
{
pair cell = q.Peek();
int x = cell.first;
int y = cell.second;
if (grid[x, y].Locatie == goal)
{
//Console.WriteLine(cell.parent.first + " " + cell.parent.second);
findPath(cell, path);
return path;
}
q.Dequeue();
// Go to the adjacent cells
for (int i = 0; i < 4; i++)
{
int adjx = x + dRow[i];
int adjy = y + dCol[i];
if (isValid(vis, adjx, adjy, grid))
{
if (grid[adjx, adjy].Loopbaar || grid[adjx, adjy].Locatie == goal)
#Locatie = Location of item in aisle, Loopbaar = whether or not a worker can walk here.
{
q.Enqueue(new pair(adjx, adjy, cell));
vis[adjx, adjy] = true;
}
}
}
}
return path;
}
And this is my pair Class which defines a cell and it's parent
class pair
{
public int first, second;
public pair parent;
public pair(int first, int second, pair parent)
{
this.first = first;
this.second = second;
this.parent = parent;
}
public String toString()
{
return (first + " " + second);
}
}
static int[] dRow = { -1, 0, 1, 0 };
static int[] dCol = { 0, 1, 0, -1 };
static bool isValid(bool[,] vis,
int row, int col, magazijnObject[,] test)
{
// If cell lies out of bounds
if (row < 0 || col < 0 ||
row >= test.GetLength(0) || col >= test.GetLength(1))
return false;
// If cell is already visited
if (vis[row, col])
return false;
// Otherwise
return true;
}
private static void findPath(pair node, List<String> path)
{
if (node != null)
{
findPath(node.parent, path);
path.Add(node.toString());
}
}
I'm curious to see whether you have any ideas on how to improve this layout in a way. As this obviously is not an improvement.
Kind regards,
D.

c# Recursion stackoverflowcrash

I am building a minesweeper game in C#, and one of my functions keeps crashing the program. The erorr message is Process is terminated due to StackOverflowException. I tried to find where is the problem in my recursion, but I didn't find it. The problem only happen if Openk is called, so I am pretty sure the problem is there. I tried to find if there is an infinite recursion, but didn't find it. What could be the problem?
public void Openk(int row, int col)
{
if (sqrs[row, col].IsBlank() == true)
{
for (int i = -1; i < 2; i++)
{
for (int j = -1; j < 2; j++)
{
if (IsValid(row - i, col - j))
{
if (sqrs[row - i, col - j].IsMine() == false)
sqrs[row - i, col - j].Open();
Openk(row - i, col - j);
}
}
}
}
}
public bool IsValid(int row, int col)
{
if (row >= n || row <= 0 || col >= n || col <= 0)
return false;
return true;
}
Your problem is that you keep looping and executing Openk on the same middle square each time. Maybe it is because of the unguarded if statement. It goes like this in your code.
You pass the selected coordinates of a square, say [5,5].
Then you loop a row before 5 (4), row 5, and a row after 5 (6).
For each row, your loop a square before the selected column 5 (4), column 5, and and the next column of 5 (6).
In your code, only when you reach the middle square (i = 0, j = 0), you execute the checking of square if it is a mine, and if it is not mine, you pass the selected coordinates after subtracting with zeros (i = 0, j = 0), which effectively loops the same spot again!
.
public void Openk(int row, int col)
{
if (sqrs[row, col].IsBlank() == true)
{
for (int i = -1; i < 2; i++)
{
for (int j = -1; j < 2; j++)
{
// Only execute the following code when checking the middle square, where i = 0, and j = 0.
if (i == 0 && j == 0) // Notice the braces I added, the code has the same effect if you don't type them.
{
// This if statement has not effect.
if (IsValid(row - i, col - j)) // It is like if (true)
{
if (sqrs[row-i, col-j].IsMine() == false)
sqrs[row - i, col - j].Open();
Openk(row - i, col - j); // row - 0 = row, col - 0 = col, your looping infinitely here.
}
}
}
}
}
}

Browse a matrix

I want to browse a matrix like these one :
I want browse the first row, get the smallest number, then browse the row matching with the precedent smallest number.
Ex : I browse the A row : I browse the cell A,A , I get 0. I don't keep it (because it's 0) I browse the cell A,D I get 5. I keep it. I browse the cell A,G I get 8 but i don't keep it because it is superior to 5. I browse cell A,K and I get 4 I keep it (< 5).
For the moment it's ok, a simple loop is sufficient to do this. Then I want to browse the row K and if possible don't browse the cell K,A because I already browsed it when I browsed the row A.
You need to loop through an upper/lower half of the matrix? I assume a matrix is an array of int arrays.
var matrix = new int[][]{ ... };
int smallest = 0;
for(int i = 0; i < matrix.Length; i++)
{
for(int j = 0; j < matrix.Length; j++)
{
int number = matrix[i][j];
if (number != 0 && number < smallest)
smallest = number;
}
}
Although, I didn't quite get
then browse the row matching with the precedent smallest number
part.
Here the solution I found :
private static IEnumerable<int> ComputeMatrix(int[,] matrix)
{
// check args
if (matrix.Rank != 2) { throw new ArgumentException("matrix should have a rank of 2"); }
if (matrix.GetUpperBound(0) != matrix.GetUpperBound(1)) { throw new ArgumentException("matrix should have the same size");}
// indice treated
List<int> treatedIndex = new List<int>();
for (int i = 0; i <= matrix.GetUpperBound(0); i++)
{
if (treatedIndex.Count == matrix.GetUpperBound(0))
break;
// distance minimum between 2 points
int distanceMin = Int32.MaxValue;
// next iteration of index
int nextI = i;
// add the index to ignore in the next iteration
int nextJ = -1;
for (int j = 0; j <= matrix.GetUpperBound(1); j++)
{
if (treatedIndex.IndexOf(j) == -1)
{
if (matrix[i, j] != 0 && matrix[i, j] < distanceMin)
{
distanceMin = matrix[i, j];
nextI = j;
nextJ = i;
}
}
}
i = nextI - 1;
treatedIndex.Add(nextJ);
yield return distanceMin;
}
}

Need help in arranging Columns in a Multiband Infragistics UltrawinGrid

I have a grid which has 4 bands and the columns in band[3] are not arranged in order as in its parent bands. My primary requirement is to arrange the Band[3] columns.
This is a part of "Export to Excel" code. The grids are already displayed in the form.
I have tried the below approach -
private UltraGrid rearrangeCol(UltraGrid grid)
{
int bandCount = grid.DisplayLayout.Bands.Count;
int band = 0;
List<String> colPos = new List<string>();
for (int i = grid.DisplayLayout.Bands[band].Columns["EndurEndInv"].Index; i < grid.DisplayLayout.Bands[band].Columns.Count; i++)
{
colPos.Add(grid.DisplayLayout.Bands[band].Columns[i].Key);
}
band++;
while (band < bandCount)
{
int initialColPos = grid.DisplayLayout.Bands[band].Columns["EndurEndInv"].Index;
for (int i = initialColPos, j = 0; i < grid.DisplayLayout.Bands[band].Columns.Count && j < colPos.Count; i++, j++)
{
if(!grid.DisplayLayout.Bands[band].Columns[i].Key.Equals(colPos[j], StringComparison.InvariantCulture))
{
grid.DisplayLayout.Bands[band].Override.AllowColSwapping = Infragistics.Win.UltraWinGrid.AllowColSwapping.WithinBand;
int xcngPos = grid.DisplayLayout.Bands[band].Columns[colPos[j]].Index;
grid.DisplayLayout.Bands[band].Columns.Insert(i, "Temp");
grid.DisplayLayout.Bands[band].Columns[xcngPos + 1].Swap(grid.DisplayLayout.Bands[band].Columns[i]);
grid.DisplayLayout.Bands[band].Columns.Remove("Temp");
grid.DisplayLayout.Bands[band].Override.AllowColSwapping = Infragistics.Win.UltraWinGrid.AllowColSwapping.Default;
}
else
continue;
}
band++;
};
return grid;
}
Actually, nothing happens when I use SWAP, the keys, index remains same.
Is there any better approach?
Yes, to rearrange to position of colums you need to work on
grid.DisplayLayout.Bands[index].Columns[colName].Header.VisiblePosition = newPos;
no need to swap the column positions, just rearrange the Header position.
This code below has not been tested and I write as an example
private UltraGrid rearrangeCol(UltraGrid grid)
{
int bandCount = grid.DisplayLayout.Bands.Count;
int band = 1;
UltraGridBand b0 = grid.DisplayLayout.Bands[0];
while (band < bandCount)
{
UltraGridBand b = grid.DisplayLayout.Bands[band]
for (int i = b0.Columns["EndurEndInv"].Index; i < b0.Columns.Count; i++)
{
string colKey = b0.Columns[i].Key;
if(b.Columns.Exists(colKey))
b.Columns[colKey].Header.VisiblePosition =
b0.Columns[colKey].Header.VisiblePosition;
}
band++;
}
return grid;
}

Categories

Resources