My program runs fine, but there is a little problem. When I add new tracks previously existing file to the ListBox, the program experiences an error. The code seems unwilling to do looping in a new file which was added in a different time. Please help me. Thanks ....
public partial class Form1 : Form
{
//...
string[] files, paths;
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
files = openFileDialog1.SafeFileNames;
paths = openFileDialog1.FileNames;
for (int i = 0; i < files.Length - 1; i++)
{
listBox1.Items.Add(files[i]);
}
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
axWindowsMediaPlayer1.URL = paths[listBox1.SelectedIndex];
}
}
Adil has caught the cause of the problem, but there's a cleaner solution:
foreach (string file in files)
{
listBox1.Items.Add(file);
}
... or even better:
listBox1.Items.AddRange(files);
In fact, I'd go even further still, and get rid of the instance variables files and paths completely. I'd either use a Tuple<string, string> or create a class for the file/class pair. Then you can add each complete data item to listBox1.Items, set the DisplayMember so that the file part is displayed, but when the selected index is changed, fetch the path from the selected item. Then there's no need to mess around with indexes at all.
You are adding one file less then the files exists, When you will access the last
Change
for (int i = 0; i < files.Length - 1; i++)
{
listBox1.Items.Add(files[i]);
}
To
for (int i = 0; i < files.Length; i++)
{
listBox1.Items.Add(files[i]);
}
Edit based on comments by OP
You might be adding the files in listbox more then once by clicking button1. This will add new files in listbox but the arrays will loose previous items in the array and the count in array will become less then the items in listbox.
private void button1_Click(object sender, EventArgs e)
{
listBox1.Items.Clear(); //Clear the items of list box to keep the same items in both listbox and in array paths.
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
files = openFileDialog1.SafeFileNames;
paths = openFileDialog1.FileNames;
for (int i = 0; i < files.Length ; i++)
{
listBox1.Items.Add(files[i]);
}
}
}
If you want to keep the previous selection then use list instead of arrays as list can grow more easily then the array.
string[] files;
List<string> paths = new List<string>() ;
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
files = openFileDialog1.SafeFileNames;
paths.AddRange(openFileDialog1.FileNames.ToList());
for (int i = 0; i < files.Length; i++)
{
listBox1.Items.Add(files[i]);
}
}
}
I don't think the problem is with adding items to the array. The more likely cause is the SelectedIndexChanged event handler. You should bounds check SelectedIndex to be sure it is valid.
int idx = listBox1.SelectedIndex;
if (paths != null && idx > 0 && idx < paths.Length)
{
axWindowsMediaPlayer1.URL = paths[idx];
}
I think both Jon and Adil are absolutely correct and you can definitely use their code to fix part of the problem. But, my guess is that you don't have any elements in paths and so when you try to get an element from it, it throws you an exception. Can you try the following code:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (paths.Length >= listBox1.SelectedIndex)
axWindowsMediaPlayer1.URL = paths[listBox1.SelectedIndex];
}
See if you're still thrown an exception and if not, then you have another problem of why your paths variable is not being set or why the listbox selected index is greater than the elements in the variable.
Related
I’m a student working on a class project to store string values into an array[10] using a “Store” button. Then the “Display” button will display the string values in the array[10] in a list box. Extra credit if we display the position too.
Currently when I click the “Store” button I do see the message the value was stored. But when I click the “Display” button the list box shows 10 “0”. Every time I make it only makes it worse so I’m not sure what I’m missing and overlooking.
My global variables
string[] results = new string[10];
string value;
I’m using the for loop to take the string value in the “ResultLabel” to store them in the array[10] until all spaces are take, total of 10 values. The “StoreLabel” displays the message that the value was stored.
protected void StoreButton_Click(object sender, EventArgs e)
{
for (int i = 0; i < results.Length; i++)
{
results[i] = ResultLabel.Text.ToString();
}
StoreLabel.Text = "Results have been stored";
}
Then I believe I’m taking the values from the results[10] array and displaying those values in the list box.
protected void DisplayButton_Click(object sender, EventArgs e)
{
DisplayListBox.Items.Clear();
for (int i = 0; i < results.Length; i++)
{
DisplayListBox.Items.Add(results[i].ToString());
}
}
You can append the index to string.
private void StoreButton_Click(object sender, EventArgs e)
{
for (int i = 0; i < results.Length; i++)
{
results[i] = ResultLabel.Text.ToString();
}
StoreLabel.Text = "Results have been stored";
}
private void DisplayButton_Click(object sender, EventArgs e)
{
DisplayListBox.Items.Clear();
for (int i = 0; i < results.Length; i++)
{
DisplayListBox.Items.Add($"{results[i].ToString()} - {i}");
}
}
I understand your project requires you to use an array and to limit it to 10 items. Those requirements might be simplified if we let the ListBox do all the hard work. I'd like to offer an easy way to get strings into the ListBox with the idea that you can then adapt this strategy to meet your project requirements.
The ListBox is simple to work with if we tell it to use our list as the source of the items it displays. Then all we have to do is add an item to this list and tell the ListBox to Refresh() its contents.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
listBoxDisplay.DataSource = Values;
}
// Here is our list of strings
BindingList<string> Values = new BindingList<string>();
private void buttonStore_Click(Object sender, EventArgs e)
{
// We look at the value in the textbox and add it to list...
Values.Add((Values.Count + 1).ToString() + " - " + textBoxValueToAdd.Text);
// …and tell the ListBox to update itself from the list
listBoxDisplay.Refresh();
}
}
I am currently working on a homework assignment that I am struggling with. The goal of the program is to:
Create a program that allows users to record and view names of up to 1000 events. The names of the events are to be stored in an array. The names can be stored and viewed sequentially only: I,e, the first time the user presses “Set” to store a name, it would be placed in index 0 of the array; the second time the user stores a name it would be stored in index 1, etc. Similarly, the first time the user presses “View”, the item found in index 0 of the array is shown to the user; the second time the user presses “View”, the item found in index 1 of the array is shown, etc.
When the user presses the “Set” button (btnSet), an event name is inserted into the array in the next free index, sequentially as described above. The name to insert to the array is taken from txtEventName.
When the user presses the button “View” (btnView), the name of the next event to view sequentially (as described above) is shown to the user. The event name is shown to the user in txtName.
I currently have the code:
namespace ArrayHW
{
public partial class Form1 : Form
{
int[] eventsArray;
const int SIZE = 1000;
public Form1()
{
InitializeComponent();
}
private void btnSet_Click(object sender, EventArgs e)
{
eventsArray = new int[SIZE];
for (int index = 0; index < eventsArray.Length - 1; index++)
{
eventsArray[index] = Convert.ToInt32(txtEventName.Text);
}
}
private void btnView_Click(object sender, EventArgs e)
{
for (int index = 0; index < eventsArray.Length- 1; index++)
{
Debug.WriteLine(eventsArray[index]);
txtName.Text = Convert.ToString(eventsArray[index]);
}
}
}
}
When I run the form, I only get the result for index = 0,1, 2, 3, etc or whatever I had just input into the array in
private void btnSet_Click(object sender, EventArgs e)
{
eventsArray = new int[SIZE];
for (int index = 0; index < eventsArray.Length - 1; index++)
{
eventsArray[index] = Convert.ToInt32(txtEventName.Text);
}
}
rather than it showing up in sequential order like it is supposed to. Could anyone show me a better way to approach this problem, or help me find out what I am doing wrong? Thank you very much.
Please read the comments in the code block. Hopefully that will help you resolve your problem.
public partial class Form1 : Form
{
const int SIZE = 1000;
int[] eventsArray = new int[SIZE];
//as per your requirement, you would need these
//to display and set items at proper index in the array.
int _setIndex = 0;
int _viewIndex = 0;
public Form1()
{
InitializeComponent();
}
private void btnSet_Click(object sender, EventArgs e)
{
//this is where your problem is. Every time the Set btn is clicked,
//you are creating a new array. Therefore you are only seeing what you added in the
//last click. Anything that was added to the array on the prior clicks are lost because
//you just created a new array with the line below.
//eventsArray = new int[SIZE];
//You would need to comment the line above because this is code block is being
//executed on every btnSet click. New up this array only once by moving this to global scope.
//for (int index = 0; index < eventsArray.Length - 1; index++)
//{
// eventsArray[index] = Convert.ToInt32(txtEventName.Text);
//}
//Since we have created fields to keep track of _setIndex, all we need to do is:
if (_setIndex < SIZE)
{
eventsArray[_setIndex] = Convert.ToInt32(txtEventName.Text);
_setIndex++;
}
}
private void btnView_Click(object sender, EventArgs e)
{
//this wont be necessary.
//for (int index = 0; index < eventsArray.Length - 1; index++)
//{
// Debug.WriteLine(eventsArray[index]);
// txtName.Text = Convert.ToString(eventsArray[index]);
//}
if(eventsArray.Length > _viewIndex)
{
txtName.Text = Convert.ToString(eventsArray[_viewIndex]);
//this is to fulfill the requirement below:
// Similarly, the first time the user presses “View”, the item found in index 0
// of the array is shown to the user; the second time the user presses “View”,
// the item found in index 1 of the array is shown, etc.
_viewIndex++;
}
}
}
Try this:
int[] eventsArray = new int[SIZE];
int index = 0;
const int SIZE = 1000;
private void btnSet_Click(object sender, EventArgs e)
{
eventsArray[index++] = Convert.ToInt32(txtEventName.Text);
}
private void btnSzures_Click(object sender, EventArgs e)
{
for (int n = listBox1.Items.Count - 1; n >= 0; --n)
{
string a = txtszuro.Text;
if (listBox1.Items[n].ToString().Contains(a))
{
listBox1.Items.RemoveAt(n);
}
}
}
I would like to do the opposite thing with this btnSzures_Click. So it would add these lines not remove them. Is there a similar method where i would just need to correct a few things in this code?
The technical "opposite" of RemoveAt() is Insert(int index, string item). This allows you to insert the item into the Items collection that you have beginning at the specified index.
I am just looking to know this to try and clean up my code, and also for future reference.
I have a number of textBoxes.
tbPart1.Clear();
tbPart2.Clear();
tbPart3.Clear();
tbPart4.Clear();
tbPart5.Clear();
tbPart6.Clear();
tbPart7.Clear();
Is there any way I could use a loop to replace the numbers?
I tried this, but have no idea how i could run the string.
for (int i = 1; i == 7; i++)
{
string p = "tbPart" + i.ToString() + ".Clear";
}
Inside of the form's code (i.e. in a button click event handler), you can enumerate through all of the TextBox controls on the form and perform a specific action on them:
this.Controls.OfType<TextBox>().ToList().ForEach(x => x.Clear());
If you need to only clear some of the TextBox controls, you can provide a sort of filter like so:
this.Controls.OfType<TextBox>()
// Add a condition to clear only some of the text boxes - i.e. those named "tbPart..."
.Where(x=>x.Name.StartsWith("tbPart"))
.ToList().ForEach(x => x.Clear());
No, you cannot do it that way. But you can define an array or list where you put the controls and then clear them. For example:
List<TextBox> textboxes = new List<TextBox>();
textboxes.Add(tbPart1);
textboxes.Add(tbPart2);
textboxes.Add(tbPart3);
...
Then when you want to clear them
foreach (var tb in textboxes)
tb.Clear();
TextBox[] boxes = new [] {
tbPart1,
tbPart2,
tbPart3,
tbPart4,
tbPart5,
tbPart6,
tbPart7
};
for (int i = 0; i < boxes.Length; i++)
{
boxes[i].Clear();
}
i think you should use an array of textbox then you can do a loop depends the count of numbers of textboxes.
foreach(Control ctrl in this.Controls)
{
if(ctrl.GetType() == typeof(TextBox))
{
ctrl.Text = String.Empty;
}
}
Answer number one by using Control name inside panel1
private void button2_Click(object sender, EventArgs e)
{
string currentCtrlName;
for (int i = 0; i < panel1.Controls.Count; i++)
{
currentCtrlName = "textBox" + (i+1).ToString();
panel1.Controls[currentCtrlName].Text = "";
}
}
==================
Answer number one by using Control index as a child inside panel1
private void button2_Click(object sender, EventArgs e)
{
for (int i = 0; i < panel1.Controls.Count; i++)
{
panel1.Controls[i].Text = "";
}
}
==================
I have a DataBound "CheckedListBox", I need to check some items on it. I tried with following code...
if (!string.IsNullOrEmpty(search.Languages))
{
string[] langs = search.Languages.Split(',');
for (int i = 0; i < (langs.Length - 1); i++)
{
for (int j = 0; j < clbLang.Items.Count; j++)
{
string lng = clbLang.Items[j] as string;
if (lng.Trim() == langs[i])
{
clbLang.SetItemChecked(j, true);
break;
}
}
}
}
No errors, debuged execution is going through "checking" process, but finally I cannot see anything checked on it.
Then I have added a button and added following code to it. (upon click check all the items)
private void button9_Click(object sender, EventArgs e)
{
for (int i = 0; i < clbLang.Items.Count; i++)
{
clbLang.SetItemChecked(i, true);
}
}
It is "checking" all the items, Please tell me if anyone can see a issue here...?
Finally found out, it is a Bug introduced by MS.
It is well explained here.
The issue is easy to reproduce. Just hide and show a databound
CheckedListBox and you will notice how
the previously checked items get
unchecked.
CheckedListBox SetItemChecked method not working
So we have to find a workaround... I tried follwing way, it is working nice...
At the place where I was calling checking of items I have added following... I am adding what I need to check in Tag of the control.
if (!string.IsNullOrEmpty(search.Languages))
{
clbLang.Tag = search.Languages;
}
Then, following code in that control's "VisibleChanged()" event.
private void clbLang_VisibleChanged(object sender, EventArgs e)
{
string lngs = clbLang.Tag as string;
if (!string.IsNullOrEmpty(lngs))
{
string[] langs = lngs.Split(',');
foreach (string lang in langs)
{
int j = 0;
foreach (DataRowView row in clbLang.Items)
{
if (row != null)
{
string lng = row[1] as string;
if (lng.Trim() == lang)
{
clbLang.SetItemChecked(j, true);
break;
}
}
j++;
}
}
}
}
This works well with me, hope it will benefit you...