I'm trying to make my own calendar and want to initialize the days in the calendar based on the month.
XAML:
<TextBlock x:Name="day0" Grid.Column="0" Grid.Row="0" Text="0" Style="{StaticResource DayTextBlock}"/>
C#:
List<UIElement> controls = new List<UIElement>();
controls.Add(day0);
controls.Add(day1);
controls.Add(day2);
controls.Add(day3);
controls.Add(day4);
controls.Add(day5);
controls.Add(day6);
for (int i = 0; i < daysInMonth; i++)
{
day0.Text = i.ToString(); // I can change it this way but don't want to do this for all 30 days
controls[i].Text = i.ToString(); // This is more so what I want to do.
}
Thanks for any help. I'm really stuck here. If you know of a better way of going about this I'd be very open to it.
I did a similar thing in the past and I proceeded as following:
TextBlock CreateDay(int dayNumber)
{
return new TextBlock()
{
Text = dayNumber.ToString()
// Here you set you other default properties, common to all TextBlocks
};
}
TextBlock day;
for (int i = 1; i < daysInMonth; i++)
{
int position = i - 1;
day = CreateDay(i);
// The '7' is the number of columns that your grid has
Grid.SetRow(day, position / 7);
Grid.SetColumn(day, position % 7);
yourGridName.Children.Add(day);
}
Please, let me know if this worked as you wanted
Thank you for the help Filippo Ferrario. I used what you said and made this.
List<Button> buttonList = new List<Button>();
List<TextBlock> textList = new List<TextBlock>();
for (int i = 0; i < daysInMonth; i++)
{
buttonList.Add(new Button());
textList.Add(new TextBlock());
textList[i].Text = "\t" + i;
}
for (int i = 0; i < daysInMonth; i++)
{
textList[i].Style = textStyle;
buttonList[i].Style = buttonStyle;
if (column > 6)
{
column = 0;
row++;
}
Grid.SetColumn(textList[i], column);
Grid.SetColumn(buttonList[i], column);
column++;
Grid.SetRow(textList[i], row);
Grid.SetRow(buttonList[i], row);
calNum.Children.Add(buttonList[i]);
calNum.Children.Add(textList[i]);
}
This is the full code for my calendar if anyone needs it.
private void displayDays()
{
DateTime dateTime = DateTime.Now;
Month.Text = dateTime.ToString("MMMM"); //month title
DateTime startOfMonth = new DateTime(dateTime.Year, dateTime.Month, 1);
int daysInMonth = DateTime.DaysInMonth(dateTime.Year, dateTime.Month);
int dayOfWeek = Convert.ToInt32(startOfMonth.DayOfWeek.ToString("d")) + 1; //https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tostring?view=net-6.0#system-datetime
List<Button> buttonList = new List<Button>();
List<TextBlock> textList = new List<TextBlock>();
for (int i = 0; i < daysInMonth; i++)
{
buttonList.Add(new Button());
textList.Add(new TextBlock());
textList[i].Text = "\t" + i;
}
//calNum is a grid I made in the XAML
calNum.ColumnDefinitions.Add(new ColumnDefinition());
calNum.ColumnDefinitions.Add(new ColumnDefinition());
calNum.ColumnDefinitions.Add(new ColumnDefinition());
calNum.ColumnDefinitions.Add(new ColumnDefinition());
calNum.ColumnDefinitions.Add(new ColumnDefinition());
calNum.RowDefinitions.Add(new RowDefinition());
calNum.RowDefinitions.Add(new RowDefinition());
calNum.RowDefinitions.Add(new RowDefinition());
calNum.RowDefinitions.Add(new RowDefinition());
calNum.RowDefinitions.Add(new RowDefinition());
int row = 0;
int column = 6;
column += dayOfWeek;
Style textStyle = this.FindResource("DayTextBlock") as Style;
Style buttonStyle = this.FindResource("DayButton") as Style;
for (int i = 0; i < daysInMonth; i++)
{
textList[i].Style = textStyle;
buttonList[i].Style = buttonStyle;
if (column > 6)
{
column = 0;
row++;
}
Grid.SetColumn(textList[i], column);
Grid.SetColumn(buttonList[i], column);
column++;
Grid.SetRow(textList[i], row);
Grid.SetRow(buttonList[i], row);
calNum.Children.Add(buttonList[i]);
calNum.Children.Add(textList[i]);
}
}
Related
I am creating radio buttons programatically for each element in an array/list and place them in a windows form.
Right now every new radio button is place under the previous one. How can i manage to start a new column after e.g. 4/5 radio buttons? The new column should appear on the right side of the previous radio-buttons.
This is my code so far:
for (int i = 0; i < startShapes.Count; i++)
{
RadioButton rdb = new RadioButton();
rdb.Text = startShapes.Values.ElementAt(i).Equals("") ? startShapes.Keys.ElementAt(i) : startShapes.Values.ElementAt(i);
rdb.Size = new Size(100, 30);
this.Controls.Add(rdb);
rdb.Location = new Point(45, 70 + 35 * i);
rdb.CheckedChanged += (s, ee) =>
{
var r = s as RadioButton;
if (r.Checked)
this.selectedString = r.Text;
};
}
How about using TableLayoutPanel?
Dictionary<string, string> startShapes = new Dictionary<string, string>();
for(int i=0;i<20;i++)
startShapes.Add("Shape " +i, "Shape " +i);
int row = 0;
int col = 0;
tableLayoutPanel1.RowStyles.Clear();
tableLayoutPanel1.ColumnStyles.Clear();
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
tableLayoutPanel1.RowCount= 0;
tableLayoutPanel1.ColumnCount = 1;
foreach (var kvp in startShapes)
{
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.AutoSize));
tableLayoutPanel1.RowCount++;
RadioButton rdb = new RadioButton();
rdb.Text = string.IsNullOrEmpty(kvp.Value) ? kvp.Key : kvp.Value;
rdb.Size = new Size(100, 30);
rdb.CheckedChanged += (s, ee) =>
{
var r = s as RadioButton;
if (r.Checked)
this.selectedString = r.Text;
};
tableLayoutPanel1.Controls.Add(rdb, col, row);
row++;
if (row == 5)
{
col++;
row = 0;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
tableLayoutPanel1.ColumnCount++;
}
}
And if you really need your solution:
int left = 45;
int idx = 0;
for (int i = 0; i < startShapes.Count; i++)
{
RadioButton rdb = new RadioButton();
rdb.Text = startShapes.Values.ElementAt(i).Equals("") ? startShapes.Keys.ElementAt(i) : startShapes.Values.ElementAt(i);
rdb.Size = new Size(100, 30);
this.Controls.Add(rdb);
rdb.Location = new Point(left, 70 + 35 * idx++);
if (idx == 5)
{
idx = 0; // reset row
left += rdb.Width + 5; // move to next column
}
rdb.CheckedChanged += (s, ee) =>
{
var r = s as RadioButton;
if (r.Checked)
this.selectedString = r.Text;
};
}
private Button[,] arrButton = new Button[10, 10];
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
arrButton[i, j] = new Button();//getting System.IndexOutOfRangeException
arrButton[i, j].Size = new Size(30, 30);
arrButton[i, j].Location = new Point(i * 30, j * 30);
arrButton[i, j].Click += new EventHandler(arrButton_Click);
this.Controls.Add(arrButton[i, j]);
}
}
this.ClientSize = new Size(300, 300);
After create, array button come up top left corner on form.
how to get array button to a place on form
#choz comment is correct, but a couple things to also consider.
Put the row value and column value in constant variables and use the variables, instead of directly using a number repeatedly.
Example:
private const ROW = 10;
private const COL = 10;
private Button[,] arrButton = new Button[ROW, COL];
...
for (int i = 0; i < ROW; i++)
{
// Change from your code -|
// |----------
// V
for (int j = 0; j < COL; j++)
{
// Create your buttons
}
}
If you are going to use constant numerals, then reference the GetUpperBound() from your array to know the last index value of each dimension.
Example:
private Button[,] arrButton = new Button[10, 10];
...
// GetUpperBound(0) = last index of rows (9 in this case)
for (int i = 0; i <= arrButton.GetUpperBound(0); i++)
{
// Change from your code -|
// |----------
// V GetUpperBound(1) = last index of columns (9 in this case)
for (int j = 0; j <= arrButton.GetUpperBound(1); j++)
{
// Create your buttons
}
}
Syntax error! Your second loop should be:
for (int j = 0; j < 10; j++)
You put "i" instead of "j",
Normally, when you get an System.IndexOutOfRangeException. The debugger error is telling you that the loop or loops you are using are counting the elements more than you specific. Check The count of elements you tinkering with.
I think you are making a mistake in inner loop. Can you please paste this and try to run:
private Button[,] arrButton = new Button[10, 10];
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)//Changed i to j
{
arrButton[i, j] = new Button();
arrButton[i, j].Size = new Size(30, 30);
arrButton[i, j].Location = new Point(i * 30, j * 30);
arrButton[i, j].Click += new EventHandler(arrButton_Click);
this.Controls.Add(arrButton[i, j]);
}
}
this.ClientSize = new Size(300, 300);
How to set wpf grid rowspan programmatically? I am using mvvm pattern.
I have grid lines enabled and the below doesn't work:
RowDefinition row0 = new RowDefinition();
myGrid.RowDefinitions.Add(row0)
for (int i = 1; i <= RowsCount; i++)
{
RowDefinition row = new RowDefinition();
myGrid.RowDefinitions.Add(row);
TextBlock txt3 = new TextBlock();
txt3.Text = i.ToString();
txt3.FontSize = 12;
txt3.FontWeight = FontWeights.Bold;
Grid.SetRow(txt3, i);
myGrid.Children.Add(txt3);
}
ColumnDefinition column0 = new ColumnDefinition();
myGrid.ColumnDefinitions.Add(column0);
char c = 'A';
for (int i = 1; i <= ColumnsCount; i++)
{
ColumnDefinition column = new ColumnDefinition();
myGrid.ColumnDefinitions.Add(column);
TextBlock txt3 = new TextBlock();
txt3.Text = c.ToString();
txt3.FontSize = 12;
txt3.FontWeight = FontWeights.Bold;
Grid.SetColumn(txt3, i);
myGrid.Children.Add(txt3);
switch (i)
{
case 1:
for (int j = 1; j <= RowsCount; j++)
{
TextBlock txt = new TextBlock();
txt.Text = ColumnAROI[j-1].ToString();
Grid.SetRow(txt, j);
Grid.SetColumn(txt, i);
Grid.SetRowSpan(txt, 2);
// Grid.SetRowSpan(txt, TubeRowSpan[j]);
myGrid.Children.Add(txt);
}
break;
}
c++;
}
for (int j = 1; j <= RowsCount; j++)
{
TextBlock txt = new TextBlock();
txt.Text = ColumnAROI[j-1].ToString();
Grid.SetRow(txt, j);
Grid.SetColumn(txt, i);
Grid.SetRowSpan(txt, TubeRowSpan[j]);
myGrid.Children.Add(txt);
}
TubeRowSpan is an ObservableCollection of type int and defined as below. It contains all 1's except at position 2 (3rd element).
private ObservableCollection<int> _TubeRowSpan = new ObservableCollection<int>();
public ObservableCollection<int> TubeRowSpan
{
get { return _TubeRowSpan; }
set
{
if (_TubeRowSpan != value)
{
_TubeRowSpan = value;
RaisePropertyChanged(() => TubeRowSpan);
}
}
}
You'll have to post the rest of your code, notably how you're creating your row definitions. The following code creates 3 rows for each element and sets the rowspan to 2, it's easy to see from the result that it's working as expected:
int numChildren = 10;
int numRows = numChildren * 3;
for (int j = 0; j < numRows; j++)
this.myGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(30) });
for (int j = 0; j < numChildren; j++)
{
TextBlock txt = new TextBlock();
txt.Background = Brushes.AliceBlue;
txt.Text = "Row " + Convert.ToString(j);
Grid.SetRow(txt, j*3);
Grid.SetRowSpan(txt, 2);
myGrid.Children.Add(txt);
}
I suspect there's something wrong with your RowDefinitions which is causing them to collapse to a height of 0 making it look like it's not working when in fact it is. Try replacing your entire code with mine and then replace your own parts back in bit by bit.
My question is: When I click some Checkbox, how can I get the current checkbox control's index from DataGridView
Here is my snick code
dataGridView2.RowCount = 5;
dataGridView2.ColumnCount = 4;
for (int i = 0; i < dataGridView2.ColumnCount; i++)
{
for (int j = 0; j < dataGridView2.RowCount; j++)
{
box = new CheckBox();
box.Text = "MyDate";
//box.Size = new System.Drawing.Size(15, 15);
dataGridView2.Controls.Add(box);
Rectangle rec = dataGridView2.GetCellDisplayRectangle(i, j, true);
box.Left = rec.Left;
box.Top = rec.Top;
}
}
}
It looks like that you try adding pure CheckBoxes to your DataGridView without using a DataGridViewCheckBoxColumn, the solution for this approach is simple like this:
for (int i = 0; i < dataGridView2.ColumnCount; i++)
{
for (int j = 0; j < dataGridView2.RowCount; j++)
{
box = new CheckBox();
box.Text = "MyDate";
//box.Size = new System.Drawing.Size(15, 15);
dataGridView2.Controls.Add(box);
Rectangle rec = dataGridView2.GetCellDisplayRectangle(i, j, true);
box.Left = rec.Left;
box.Top = rec.Top;
//Added code
box.Tag = new Point(i,j);
box.Click += CheckBoxesClicked;
}
}
private void CheckBoxesClicked(object sender, EventArgs e){
CheckBox chb = sender as CheckBox;
if(chb.Tag != null) {
Point coord = (Point)chb.Tag;
MessageBox.Show(string.Format("Row index: {0}\nColumn index: {1}", coord.Y, coord.X);
}
}
You should use a DataGridViewCheckBoxColumn instead, with that approach, you can handle the event CellContentClick...
if you are using the CellContentClick event or any other event that you get the DataGridViewCellEventArgs then you have ColumnIndex and RowIndex properties that are the column and row of the cell changed
Check this links. This gives you details about grid view.
http://msdn.microsoft.com/en-us/library/ms972814.aspx
http://msdn.microsoft.com/en-us/library/aa479344.aspx
I'm trying this code:
arrList = new List<CheckBox>();
for (int j = 0; j < 20; j++)
{
CheckBox check = new CheckBox();
arrList.Add(check);
}
CheckBox[] cb = arrList.ToArray();
for (int i = 0; i < 20; i++)
{
cb[i].Text = "sometext";
cb[i].Location = new System.Drawing.Point(10, 15 + i * 20);
cb[i].BackColor = System.Drawing.Color.Silver;
cb[i].Name = "somename";
cb[i].Size = new System.Drawing.Size(59, 17);
cb[i].Checked = true;
groupBox1.Controls.Add(cb[i]);
}
How can I add a vertical scroll bar there? (maybe I should use something instead of groupbox?)
You could use a Panel control and set it's AutoScroll property to True