edit listview row items or adding to it - c#

Im trying to edit a listview row's items names.
This is the function i use to add the items to list view
public static void AddRow(this ListView lvw, int image_index,
string item_title, params string[] subitem_titles)
{
// Make the item.
ListViewItem new_item = lvw.Items.Add(item_title, 1);
// Set the item's image index.
new_item.ImageIndex = image_index;
// Make the sub-items.
for (int i = subitem_titles.GetLowerBound(0);
i <= subitem_titles.GetUpperBound(0);
i++)
{
new_item.SubItems.Add(subitem_titles[i]);
}
}
This is what i have tried so far, Trying to edit the text or even add new items
public static void EditRow(this ListView lvw, int image_index,
string item_title, params string[] subitem_titles)
{
//ListViewItem lvi = lvw.Items[image_index];
for (int i = 0; i < lvw.Items[image_index].SubItems.Count; i++)
{
lvw.Items[image_index].SubItems[i].Text = subitem_titles[i];
}
}
.
Update:
Think i have worked it out
public static void EditRow(this ListView lvw, int image_index,
string item_title, params string[] subitem_titles)
{
if (lvw.InvokeRequired)
lvw.Invoke(new MethodInvoker(delegate
{
for (int i = subitem_titles.GetLowerBound(0); i <= subitem_titles.GetUpperBound(0); i++)
lvw.Items[image_index].SubItems[i + 1].Text = subitem_titles[i];
}));
else
{
for (int i = subitem_titles.GetLowerBound(0);i <= subitem_titles.GetUpperBound(0);i++)
lvw.Items[image_index].SubItems[i + 1].Text = subitem_titles[i];
}
}

Related

Form only recognizes one Groupbox property

I am trying to populate a run-time created Form.
First I create my text-properties that's supposed to each button
public static List<string> GetDialogs()
{
dialogs = new List<string>();
var tempString = "";
for (int i = 1; i <= FormSize.getHorizontalButtonCount(); i++)
{
for (int j = 1; j <= FormSize.getVerticalButtonCount(); j++)
{
//fx
tempString = $"{i}x{j*multiplier}";
dialogs.Add(tempString);
}
}
return dialogs;
}
and my list ends up like "1x5", "1x10", "1x15", "2x5" etc
Then I create all my Radiobuttons
public static List<RadioButton> CreateRadioButtons()
{
List<RadioButton> radioButtons = new List<RadioButton>();
for (int i = 0; i < FormSize.getRadioButtonCount(); i++)
{
var tempName = $"btn{i}";
radioButtons.Add(new RadioButton());
radioButtons[i].Name = tempName;
}
return radioButtons;
}
Which just creates a lot of buttons with some names like btn1 etc
Then I populate my Radiobutton-list with my dialog-list
private List<RadioButton> PopulateRadiobuttons()
{
dialogs = FormDialogs.GetDialogs();
List<RadioButton> tempRadioButtons = RadioButtonCreator.CreateRadioButtons();
for (int i = 0; i < FormSize.getRadioButtonCount(); i++)
{
tempRadioButtons[i].Text = dialogs[i];
}
return tempRadioButtons;
}
Now my Radiobuttons both contain a name like btn20 and a text like 4x30
Then I first populate a GroupBox with all my RadioButton elements before lastly populating my form with the groupbox.
public Form PopulateForm()
{
_box = new GroupBox();
radioButtons = PopulateRadiobuttons();
for (int i = 0; i < radioButtons.Count; i++)
{
_box.Controls.Add(radioButtons[i]);
}
_form.Controls.Add(_box);
return _form;
}
Besides all this, when I call this method to create a form it's only the first radiobutton that appears, the 1x5 one.
How could I go on about including all my buttons in my Form?
Here's what I do so far
private void Bt1_Click(object sender, Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs e)
{
FormCreator fm = new FormCreator();
f1 = fm.PopulateForm();
f1.Show();
}

Adding an Items into Listview

I have completely split the string in text file that is delimited by a comma.
My problem is that I cannot show the data on my list view.
I have use this code, but when I run it and debug, there is value inside the variables. but then I finished the debugging, No Items were added in the Listview.
private void ColumnHeaders()
{
lvResult.View = View.Details;
lvResult.Columns.Add("ファイル名");
lvResult.Columns.Add("フォルダ");
lvResult.Columns.Add("比較結果");
lvResult.Columns.Add("左日付");
lvResult.Columns.Add("右日付");
lvResult.Columns.Add("拡張子");
for (int i = 0; i <= lvResult.Columns.Count; i++)
{
lvResult.Columns[i].Width = lvResult.Width / 6;
}
}
private void viewTextFile()
{
string[] lines = File.ReadAllLines(txtResultPath.Text + "A.YMD6063_new.txt");
for (int x = 0 ; x <= lines.Length; x++)
{
string[] col = lines[x].Split(new char[] { ',' });
ListViewItem lvItem = new ListViewItem();
for (int i = 0; i <= col.Length; i++)
{
lvItem.Text = col[i].ToString();
if (i == 0)
{
lvResult.Items.Add(lvItem);
}
else
{
lvResult.Items[x].SubItems[i].Text = lvItem.Text;
}
}
}
}
here is a sample code I tried. Hope this would help you.
listView1.Columns.Add("column1");
listView1.Columns.Add("column2");
listView1.Columns.Add("column3");
listView1.Columns.Add("column4");
string[] lines = new string[] { "value01,value02,value03,value04", "value11,value12,value13,value14" };
foreach (string line in lines)
{
listView1.Items.Add(new ListViewItem(line.Split(',')));
}
Set the ListView.View to Details. This can either be achieved in the Designer or programatically like this:
lvResult.View = View.Details;
Add each line of your file:
private void viewTextFile()
{
foreach(var line in File.ReadAllLines(somefilepath))
AddLineToListView(line);
}
private void AddLineToListView(string line)
{
if (string.IsNullOrEmpty(line))
return;
var lvItem = new ListViewItem(line.Split(','));
lvResult.Items.Add(lvItem);
}

Populate TreeView from listbox without using SelectedNode C#

I need to populate a TreeView without using SelectedNode property.
This TreeView must contain the items (in most cases - strings) that are in a listbox. These items should be sorted like in a simple binary tree. The root node is the first item. If some of the items is repeated, the count of this item should be increased and the output should be like that ->
-- item 2
| -- private
| - apple
or something like that. In this example, item is the root, apple should be the left child and private - the right.
I found a possible solution here but i have no idea how to do the whole thing :/
Here is my code:
public void populateBaseNodes()
{
int i;
treeView1.Nodes.Clear();
treeView1.BeginUpdate();
for (i = 0; i < L.Count(); i++)
{
if (L[i].level == 0)
{
treeView1.Nodes.Add(L[i].NodeText, L[i].NodeText);
treeView1.Nodes[treeView1.Nodes.Count - 1].Tag = L[i];
}
}
for (i = 0; i < treeView1.Nodes.Count; i++)
populateChilds(treeView1.Nodes[i]);
treeView1.EndUpdate();
treeView1.Refresh();
}
public void populateChilds(TreeNode parentNode)
{
kData parentRed = (kData)parentNode.Tag;
for (int i = parentRed.index + 1; i < L.Count; i++)
{
if (L[i].level == (parentRed.level + 1))
{
parentNode.Nodes.Add(L[i].NodeText, L[i].NodeText);
parentNode.Nodes[parentNode.Nodes.Count - 1].Tag = L[i];
populateChilds(parentNode.Nodes[parentNode.Nodes.Count - 1]);
}
if (L[i].level <= parentRed.level) break;
}
}
And this is my code for the button that will populate the treeview ->
string line;
L = new List<kData>();
for (int i = 0; i < listBox1.Items.Count; i++)
{
line = listBox1.Items[i].ToString();
L.Add(new kData());
L[i].index = i;
L[i].level = i;
ind = line.IndexOf(':');
L[i].NodeText = line.Substring(0, ind);
}
populateBaseNodes();
This is the kData class ->
public class kData
{
public int level;
public int index;
public string NodeText;
};
List<kData> L;
I will appreciate any kind of help :)

Fill DataGridView from checkedListBox

I have a checkedListBox1 and i want to convert all it's items to a DataGridView
i have the following code
string[] ar = new string[60];
for (int j = 0; j < checkedListBox1.Items.Count; j++)
{
ar[j] = checkedListBox1.Items[j].ToString();
}
dataGridView2.DataSource = ar;
but the dataGridView2 is filled with the length of the item instead of the item itself, can any one help?
These code blocks may give an idea (all is worked for me). CheckedListBox items returns a collection. It is coming from IList interface so if we use a List item as datasource for datagridview solves the problem. I used genericList as an additional class of Sample. When we use string array datagridview shows each items length. In here overried ToString returns original value.
class Sample
{
public string Value { get; set; }
public override string ToString()
{
return Value;
}
}
In form class:
private void button1_Click(object sender, EventArgs e)
{
CheckedListBox.ObjectCollection col = chk.Items;
List<Sample> list = new List<Sample>();
foreach (var item in col)
{
list.Add(new Sample { Value = item.ToString() });
}
dgw.DataSource = list;
}
This simple DataTable code appears to work...
DataTable dt = new DataTable();
dt.Columns.Add("Name", typeof(string));
for (int j = 0; j < checkedListBox1.Items.Count; j++) {
dt.Rows.Add(checkedListBox1.Items[j].ToString());
}
dataGridView1.DataSource = dt;
Because DataGridView looks for properties of containing objects. For string there is just one property - length. So, you need a wrapper for a string like this.
string[] ar = new string[60];
for (int j = 0; j < checkedListBox1.Items.Count; j++)
{
ar[j] = checkedListBox1.Items[j].ToString();
}
dataGridView1.DataSource = ar.Select(x => new { Value = x }).ToList();

Random labels in Tic Tac Toe simulation

I am working on a Tic Tac Toe simulator for a class and have run into an issue.
I created a 2-dimensional array to simulate the board and populate it with either 0 or 1 in all the boxes.
The issue I am having is getting those numbers to apply to the labels I have created (a1, a2, a3, b1, b2, etcetera).
Is there a way that my nested for loops can have each element in the array apply to a new label? I can't seem to find anything in my book or online about this.
Here is my related code:
private void newBTN_Click(object sender, EventArgs e)
{
Random rand = new Random();
const int ROWS = 3;
const int COLS = 3;
int [,] board = new int[ROWS, COLS];
for (int row = 0; row < ROWS; row++)
{
for (int col = 0; col < COLS; col++)
{
board[row, col] = rand.Next(1);
}
}
}
What are the names of the labels? I assumed below that the labels are Label0_0, Label0_1, Label1_1 and so on... This way you can find them using the row and column values.
You want to find the Label control on your form dynamically, because you don't know the name in advance while coding.
If you know the name in advance you just say: label1.Text = "1";.
But in your case, you are trying to find a particular control in each iteration of the loop. So you need to have a name for the labels so you can find them using Form.Controls.Find(string, bool) like this:
var row = 4;
var col = 6;
var l = this.Controls.Find("Label" + row.ToString() + "_" + col.ToString(), false).FirstOrDefault() as Label;
if (l == null)
{
//problem... create label?
l = new Label() { Text = "X or O" }; //the position of this need to be set (the default is 0,0)
this.Controls.Add(l);
}
else
{
l.Text = "X or O";
}
Your board stores integers, which is an internal representation of your game state. You can create a UniformGrid that holds Label for your game GUI. The code below returns a grid based on your current board. You need to add this returned grid to your MainWindow (or whatever you use) to see it.
private UniformGrid fillLabels(int[,] board)
{
int numRow = board.GetLength(0);
int numCol = board.GetLength(1);
UniformGrid g = new UniformGrid() { Rows = numRow, Columns = numCol };
for (int i = 0; i < numRow; i++)
{
for (int j = 0; j < numCol; j++)
{
Label l = new Label();
l.Content = (board[i, j] == 0) ? "O" : "X";
Grid.SetRow(l, i);
Grid.SetColumn(l, j);
g.Children.Add(l);
}
}
return g;
}
First, do not re-create (and re-initialize) Random each time you need it: it makes generated sequences skewed badly:
private static Random s_Rand = new Random();
Try not implement algorithm in the button enent directly, it's a bad practice:
private void CreateField() { ... }
private void newBTN_Click(object sender, EventArgs e) {
CreateField();
}
putting all together:
private static Random s_Rand = new Random();
private void ApplyLabelText(String name, String text, Control parent = null) {
if (null == parent)
parent = this;
Label lb = parent as Label;
if ((lb != null) && (String.Equals(name, lb.Name))) {
lb.Text = text;
return;
}
foreach(Control ctrl in parent.Controls)
ApplyLabelText(name, text, ctrl);
}
private void CreateField() {
for (Char row = 'a'; row <= 'c'; ++row)
for (int col = 1; col <= 3; ++col)
ApplyLabelText(row.ToString() + col.ToString(), s_Rand.Next(1) == 0 ? "O" : "X");
}
private void newBTN_Click(object sender, EventArgs e) {
CreateField();
}
How about you skip the INTEGER board and go directly to a Label array?
You can then do the following to loop trough all of them:
Label[,] listOfLabels; // Do also initialize this.
foreach(Label current in listOfLabels)
{
current.Text = _rand.Next(2) == 0 ? "0" : "X";
}

Categories