How to move button in array and set null of come from? - c#

I have the multi-dimensional array originalArray[X_VECTOR, Y_VECTOR] of MyButtons.
MyButton is simple created class (maybe unnecessary):
class MyButton : Button
{
private int[] id;
public MyButton()
{
id = new int[2];
}
public int[] ID
{
get
{
return id;
}
set
{
id = value;
}
}
}
In loop we fill the array of buttons:
public void fillArray() {
originalArray = new MyButton[X_VECTOR, Y_VECTOR];
int count_buttons = 0;
for (int i = 0; i < X_VECTOR; ++i)
{
for (int j = 0; j < Y_VECTOR; ++j)
{
count_buttons++;
MyButton btn = new MyButton();
btn.Name = "btn " + count_buttons;
btn.ID[0] = i;
btn.ID[1] = j;
originalArray[i, j] = btn;
}
}
}
Now, we would like to move button to right side after click in array:
protected void MyBtnClick(object sender, EventArgs e) {
if (sender != null) {
MyButton myclickbutton = (MyButton)sender;
int x = myclickbutton.ID[0];
int y = myclickbutton.ID[1];
MyButton temp = originalArray[x, y];
temp.Location = new Point(curr_pos_x + 55, curr_pos_y);
temp.ID[0] = x;
temp.ID[1] = y + 1; // new coordinate y
originalArray[x, y + 1] = temp;
temp = null;
// originalArray[x, y] = null;
}
}
NULL is not set. What I'm going wrong?
I need this ilustration:
BEFORE CLICK:
originalArray[0,0] = btn instance;
originalArray[0,1] = null;
AFTER CLICK:
originalArray[0,0] = null;
originalArray[0,1] = btn instance;
EDIT:
When I tried this:
protected void MyBtnClick(object sender, EventArgs e) {
if (sender != null) {
MyButton myclickbutton = (MyButton)sender;
int x = myclickbutton.ID[0];
int y = myclickbutton.ID[1];
myclickbutton.Location = new Point(curr_pos_x + 55, curr_pos_y);
myclickbutton.ID[0] = x;
myclickbutton.ID[1] = y + 1;
originalArray[x, y + 1] = myclickbutton;
originalArray[x, y] = null;
}
}
That maybe OK, but when I was testing this
if ((originalArray[i, j].Name == testArray[i, j].Name)) ...
This line gets me NullReferenceException.
This function I same like fillArray above, and this I call in constructor:
public void createTestArray() {
testArray = new MyButton[X_VECTOR, Y_VECTOR];
int count_buttons = 0;
for (int i = 0; i < X_VECTOR; ++i)
{
for (int j = 0; j < Y_VECTOR; ++j)
{
count_buttons++;
MyButton btn = new MyButton();
btn.Name = "btn " + count_buttons;
testArray[i, j] = btn;
}
}
}

You made one of items of array to be null, now you go through all of them, null items throw you an exception. Just check if item is not null before names are compared and you will not get an exception

You're getting a message saying Null is not set. You have commented out the line that returns the original x and y entry in the multi-dimensional array to null. What you've got at the moment is:
originalArray[0,0] = btn instance;
originalArray[0,1] = temp;
Remove the comments from your last line and you should erase btn instance in 0,0.

Related

ListView SelectedIndexChanged items getting inserted twice

I have a list of clauses in my database and a listview in my custom pane in VSTO.
When I select or drag and drop a list item, it gets copied twice. I found this answer.
Listview ItemSelectionChanged fires twice?
But I dont have a isSelected method for my EventArgs e.
Below is my code, please help me out, I want the data/text to be copied only once.
private void clauseList_SelectedIndexChanged(object sender, EventArgs e)
{
ListView.SelectedListViewItemCollection col = clauseList.SelectedItems;
string temp = clauseList.FocusedItem.Text;
clauseList.DoDragDrop(temp, DragDropEffects.Move);
Microsoft.Office.Interop.Word.Selection currentSelection = Globals.ThisAddIn.Application.Selection;
Microsoft.Office.Interop.Word.Range range = currentSelection.Range;
currentSelection.TypeText(temp);
currentSelection.TypeParagraph();
clslst(select);
}
public void clslst(object s)
{
DataAccess data = new DataAccess();
List<ClauseDetails> details = new List<ClauseDetails>();
details.AddRange(data.ClausesRelated(s));
string FromtextFromDoc;
FromtextFromDoc = Globals.ThisAddIn.Application.Selection.Text;
Microsoft.Office.Interop.Word.Document docs = Globals.ThisAddIn.Application.ActiveDocument;
List<string> clslist = new List<string>();
string aa = "";
int f = 0;
string tempindex = "";
foreach (Paragraph paragraph in docs.Paragraphs)
{
Style style = paragraph.get_Style() as Style;
string styleName = style.NameLocal;
//var sty = style.Font;
//fontstyle = sty.Name;
//fontsize = sty.Size;
if (styleName.Equals("Heading 1"))
{
f += 1;
if (f == 2)
{
tempindex = aa;
f = 0;
clslist.Add(tempindex);
aa = "";
}
}
if (f > 0)
{
aa += paragraph.Range.Text;
}
}
clslist.Add(aa);
List<string> ClausesNotPresent = new List<string>();
List<string> ClausesPresent = new List<string>();
for (int i = 0; i < clslist.Count; i++)
{
for (int j = 0; j < details.Count; j++)
{
if (clslist[i].Contains(details[j].clausetitle) || clslist[i].Contains(details[j].clause))
{
ClausesPresent.Add(details[j].clausetitle + "\n" + details[j].clause);
}
}
}
List<string> test = new List<string>();
for (int z = 0; z < details.Count; z++)
{
test.Add(details[z].clausetitle + "\n" + details[z].clause);
}
if (ClausesPresent.Count < details.Count)
{
ClausesNotPresent.AddRange(test.Except(ClausesPresent));
}
for(int m=0;m<ClausesNotPresent.Count;m++)
{
ClausesNotPresent[m] = "\n"+ ClausesNotPresent[m];
}
clauseList.Clear();
for (int i = 0; i < ClausesNotPresent.Count; i++)
{
clauseList.Items.Add(ClausesNotPresent[i]);
}
}

Why won't the label populate

I have been trying to create a chess strategy application. I seem to be having issues with trying to get the label1 control to populate during run time. I am actually pretty new to the idea of dynamically creating events like 'mouse enter, mouse leave' How do I get the label to show the coordinates in the mouse enter event
int currentXposition, currentYposition;
const string positionLabel = "Current Position: ";
private void Test_Load(object sender, EventArgs a)
{
var temp=Color.Transparent; //Used to store the old color name of the panels before mouse events
var colorName = Color.Red; //Color used to highlight panel when mouse over
int numBlocks = 8; //Used to hold the number of blocks per row
int blockSize=70;
//Initialize new array of Panels new
string[,] Position = new string[8, 8];
Panel[,] chessBoardPanels = new Panel[numBlocks, numBlocks];
string Alphabet = "A,B,C,D,E,F,G,H";
string Numbers ="1,2,3,4,5,6,7,8";
string[] alphaStrings = Numbers.Split(',');
string[] numStrings=Numbers.Split(',');
// b = sub[0];
int FirstValue, SecondValue;
//Store Position Values
for (int firstValue = 0; firstValue < 8; ++firstValue)
{
FirstValue = Alphabet[firstValue];
for (int SecValue = 0; SecValue < 8; ++SecValue)
{
SecondValue = Numbers[SecValue];
Position[firstValue, SecValue] = alphaStrings[firstValue] + numStrings[SecValue];
}
}
//Loop to create panels
for (int iRow = 0; iRow < numBlocks; iRow++)
for (int iColumn = 0; iColumn < numBlocks; iColumn++)
{
Panel p = new Panel();
//set size
p.Size = new Size(blockSize, blockSize);
//set back colour
p.BackColor = (iRow + (iColumn % 2)) % 2 == 0 ? Color.Black : Color.White;
//set location
p.Location = new Point(blockSize *iRow+15, blockSize * iColumn+15);
chessBoardPanels[iRow, iColumn] = p;
chessBoardPanels[iRow,iColumn].MouseEnter += (s,e) =>
{
currentXposition = iRow;
currentYposition = iColumn;
var oldColor = (s as Panel).BackColor;
(s as Panel).BackColor = colorName;
temp = oldColor;
label1.Text = Position[iRow, iColumn];
};
chessBoardPanels[iRow, iColumn].MouseLeave += (s, e) =>
{
(s as Panel).BackColor = temp;
};
groupBox1.Controls.Add(p);
}
}
Try this.. It was not populating because of a out of range.. iRow always = 8...
Add this class to your project.
public class ChessSquare
{
public string Letter { get; set; }
public int Number { get; set; }
public Color Color { get; set; }
public string Position
{
get { return string.Format("{0}{1}", Letter, Number); }
}
public ChessSquare()
{
}
public ChessSquare(string letter, int number)
{
Letter = letter;
Number = number;
}
}
Replace the FormLoad method with this:
int blockSize = 20;
Panel[,] chessBoardPanels = new Panel[8, 8];
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
ChessSquare sq = new ChessSquare(((char)(65+i)).ToString(), j);
sq.Color = (i + (j % 2)) % 2 == 0 ? Color.AliceBlue : Color.White;
Panel p = new Panel()
{ Size = new Size(blockSize, blockSize),
BackColor = sq.Color,
Tag = sq,
Location = new Point(blockSize * i + 15, blockSize * j+15),
};
p.MouseEnter+=new EventHandler(squareMouseEnter);
p.MouseLeave += new EventHandler(squareMouseLeave);
chessBoardPanels[i, j] = p;
groupBox1.Controls.Add(p);
}
}
And add those two methods to your code:
void squareMouseEnter(object sender, EventArgs e)
{
Panel p = (Panel)sender;
ChessSquare sq = (ChessSquare)p.Tag;
p.BackColor = Color.Aqua;
label1.Text = string.Format("Current position: {0}", sq.Position);
}
void squareMouseLeave(object sender, EventArgs e)
{
Panel p = (Panel) sender;
ChessSquare sq = (ChessSquare)p.Tag;
p.BackColor = sq.Color;
}
I there are several ways of doing it... This one is pretty straight forward.

Retrieve value from dynamic TextBox

I have a Button that creates a list of TextBoxes Dynamically and I also have a Button that submits the information. However I don't know how to access the values of the Textboxes. Below is the code:
if (IsPostBack)
{
ViewState["count"] = Convert.ToInt32(ViewState["count"]) + 1;
int Count = int.Parse(string.Format("{0}", ViewState["count"]));
var lstTextBox = new List<TextBox>();
for (int i = 0; i < Counter; i++)
{
TextBox txtbx = new TextBox();
txtbx.ID = string.Format("txtbx{0}", i);
// txtbx.AutoPostBack = true;
lstTextBox.Add(txtbx);
//txtbx.Text = "initial value";
}
Session["lstTextBox"] = lstTextBox;
}
protected void Button1_Click(object sender, EventArgs e)
{
int total = Counter;
for (int i = 0; i < total; i++)//Calls to createbox
CreateTextBox(i);
//Label1.Text = Counter.ToString();
if (Counter == 4)
{
Button1.Visible = false;
}
}
private int Counter
{
get { return Convert.ToInt32(ViewState["count"] ?? "0"); } //Fields button counter
set { ViewState["count"] = value; }
}
private void CreateTextBox(int j) //Creates the fields / cells
{
var box = new TextBox();
box.ID = "Textbox" + j;
box.Text = "Textbox" + j;
var c = new TableCell();
c.Controls.Add(box);
r.Cells.Add(c);
table1.Rows.Add(r);
}
How would like to have Button2 grab the values.
Thank you in advance!!
do it like this
foreach(Control c in YourControlHolder.Controls)
{
if(c is TextBox)
{
//your code here.
}
}

Plugin another project in current window

I'm creating a WPF application with a menu, when clicked on menuItem I want to show NQueens (another project) in my Window (plugin). I've placed an NQueens.dll in my CurrentDirectory to work with. To make this work I've created an assembly object to load the classes and created an instance of Nqueens.Nqueen and invoked the methods.
The NQueens project consists of a class NQueen.cs and a MainWindow.
namespace NQueens
{
public class NQueen
{
public static bool berekenQueens(int Row, int N, bool[,] bord)
{
if (Row >= N) return true; //stopconditie
for (int Col = 0; Col < N; Col++)
{
//Q toevoegen
bord[Row, Col] = true;
//Q + Q volgende Row controleren
if (bordValidatie(Row, Col, bord, N) && berekenQueens(Row + 1, N, bord))
{
return true;
}
//Q verwijderen indien niet door controle
bord[Row, Col] = false;
}
return false;
}
private static bool bordValidatie(int currentRow, int currentCol, bool[,] currentBord, int N)
{
int colstep = 1;
for (int i = currentRow - 1; i >= 0; i--)
{
//rechte lijn
if (currentBord[i, currentCol])
return false;
//linker diagonaal
if (currentCol - colstep >= 0)
{
if (currentBord[i, currentCol - colstep])
return false;
}
//rechter diagonaal
if (currentCol + colstep < N)
{
if (currentBord[i, currentCol + colstep])
return false;
}
colstep += 1;
}
return true;
}
}
}
MainWindow.xaml.cs
namespace NQueens
{
public partial class MainWindow : Window
{
public int iN { get { return Convert.ToInt32(txtN.Text); } set { txtN.Text = "" + value; } }
private bool[,] spelbord;
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
spelbord = new bool[iN, iN];
NQueen.berekenQueens(0, iN, spelbord);
visualise(iN, spelbord);
}
private void visualise(int N, bool[,] bord)
{
gridTekenen();
for (int row = 0; row < N; row++)
{
for (int col = 0; col < N; col++)
{
Rectangle rect = new Rectangle();
rect.Stretch = Stretch.Fill;
TextBlock txtB = new TextBlock();
if (spelbord[row, col])
{
SolidColorBrush mySolidColorBrush = new SolidColorBrush();
mySolidColorBrush.Color = Colors.LightGreen;
rect.Fill = mySolidColorBrush;
txtB.Text = "Q";
}
rect.SetValue(Grid.ColumnProperty, col);
rect.SetValue(Grid.RowProperty, row);
txtB.SetValue(Grid.ColumnProperty, col);
txtB.SetValue(Grid.RowProperty, row);
gridPaneel.Children.Add(rect);
gridPaneel.Children.Add(txtB);
}
}
}
private void gridTekenen()
{
gridPaneel.ShowGridLines = true;
int grooteGrid = int.Parse(txtN.Text);
RowDefinition rowDef;
ColumnDefinition colDef;
for (int i = 0; i < grooteGrid; i++)
{
rowDef = new RowDefinition();
GridLengthConverter myGridLengthConverter = new GridLengthConverter();
GridLength gl1 = (GridLength)myGridLengthConverter.ConvertFromString(150 + "*");
rowDef.Height = gl1;
colDef = new ColumnDefinition();
colDef.Width = gl1;
gridPaneel.RowDefinitions.Add(rowDef);
gridPaneel.ColumnDefinitions.Add(colDef);
}
}
}
}
Code in WPF application when clicked on the menuItem.
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
// Create an assembly object to load our classes
string path = System.Environment.CurrentDirectory + "\\NQueens.dll";
Assembly ass = Assembly.LoadFile(path);
Console.WriteLine(path);
Type objType = ass.GetType("NQueens.NQueen");
// Create an instace of NQueens.NQueen
var instance = Activator.CreateInstance(objType);
// public static bool berekenQueens(int Row, int N, bool[,] bord)
var result = objType.InvokeMember("berekenQueens",BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public,
null, instance, new object[] { 1, /* Row */ 1, /* N */ new bool[,] { {true,false} } /* bord */
});
// private static bool bordValidatie(int currentRow, int currentCol, bool[,] currentBord, int N)
var result2 = objType.InvokeMember("bordValidatie", BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.NonPublic,
null, instance, new object[] { 1, /* Row */ 1, /* N */ new bool[,] { {true,false} } /* bord */, 1
});
}
I do not know what to do now. How can I show the NQueen program in my current Window when clicked on the menuItem.
NQueen class should be any kind of wpf control descendant. If it's a simple class, it cannot communicate with its container.
So you should instanciate NQueens.MainWindow instead of NQueens.NQueen and call the Show method.

C# create 3x3 2d map with labels

Is there a way to create 3 rows with 3 colums with labels (or similar) to create a 2d "map" with data to manipulate in an easy way?
just placing 9 labels is easy but I want each labels to be accessed with the same array.
How it looks like in the form:
label1 label2 label3
label4 label5 label6
label7 label8 label9
If i need to change the property of label5 I would like to access it something like this:
labelarray[1][1].Text = "Test";
(labelarray[row][column].Property )
How do I do this?
Or could this be achieved in another way?
class Data
{
private string text;
public string Text
{
get { return text; }
set { text = value; }
}
}
class Program
{
static void Main(string[] args)
{
Data[,] map = new Data[3, 3];
map[1, 1] = new Data();
map[1, 1].Text = "Test";
}
}
Edit: fixed error.
private void button1_Click(object sender, EventArgs e)
{
string[] nine_labels = { "a", "b", "c", "d", "e", "f", "g", "h", "i" };
var labelarray= new Label[3,3];
// putting labels into matrix form
int c = 0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
var lbl = new Label();
lbl.Text = nine_labels[c];
lbl.Top = i * 100;
lbl.Left = j * 100;
labelarray[i, j] = lbl;
c++;
}
}
// adding labels to form
foreach (var item in labelarray)
{
this.Controls.Add(item);
}
// test
labelarray[1, 1].Text = "test";
}
NOTE: You'll need to add one button and call this function on Click of that button.
The answer from tehMick actually lead to a runtime exception in .NET 2.0 but, except for that, the example is straight to the point.
The types of the two dimensional array must have a public accessible property, so you can access it directly as you said:
public class DTO
{
private String myStrProperty;
public String MyStrProperty
{
get {return myStrProperty; }
set { myStrProperty = value; }
}
public DTO(string myStrProperty)
{
this.myStrProperty = myStrProperty;
}
}
class Program
{
private static Logger logger;
static void Main(string[] args)
{
DTO[,] matrix =
{
{new DTO("label1"), new DTO("label2")},
{new DTO("label3"), new DTO("label4")}
};
matrix[0, 1].MyStrProperty = "otherValue";
}
}
Here's an example that's specific to winforms. Hopefully it will answer the question a little bit better:
const int spacing = 50;
Label[][] map = new Label[3][];
for (int x = 0; x < 3; x++)
{
map[x] = new Label[3];
for (int y = 0; y < 3; y++)
{
map[x][y] = new Label();
map[x][y].AutoSize = true;
map[x][y].Location = new System.Drawing.Point(x * spacing, y * spacing);
map[x][y].Name = "map" + x.ToString() + "," + y.ToString();
map[x][y].Size = new System.Drawing.Size(spacing, spacing);
map[x][y].TabIndex = 0;
map[x][y].Text = x.ToString() + y.ToString();
}
this.Controls.AddRange(map[x]);
}
map[1][1].Text = "Test";

Categories