I'm using .net CF 3.5 to develop an application for Windows Mobile 5.0
I have a ListBox with a list of numbers in. When they click on a number in the list, it should be deleted from the list. I can get the selected item's index just fine from the list - However, I cannot seem to delete it without the application crashing. There are no errors, it will just exit with code 0.
private void DeleteOrder(object sender, EventArgs e) {
string s = (string) orders_list.SelectedItem;
int size = orders_list.Items.Count;
bool con = true;
for (int i = 0; i < size; i++) {
Debug.Write("\nIS: " + i + "\n");
if (con) {
if (s != null || s != "") {
if (orders_list.GetItemText(orders_list.Items[i]) != null) {
if (orders_list.GetItemText(orders_list.Items[i]).ToString() == s) {
if (orders_list.Items[i] != null) {
Debug.Write("ORDER IS : " + orders_list.Items[i].ToString());
orders_list.Items.Remove(orders_list.Items[i].ToString());
}
con = false;
}
}
}
}
}
input_scan.Text = "";
this.BackColor = Color.Lime;
input_scan.Focus();
}
}
}
As you can see, I've tried doing
orders_list.Items.Remove(orders_list.Items[i].ToString());
to see if I can remove the string object and I've tried using RemoveAt() to remove by index, but each time the application will keep crashing.
Any help would be appreciated as something so simple such as removing from a collection has become rather a challenge.
Related
I have been looking for a way to have a TextBox format while the user is inputting data.
I have made a hack that does what I want, but it is a bit finicky due things like when you accidentally press two keys at once which can screw with the if statements and when trying to delete the string via Delete Key by the user.
Anyway, that is not the issue and this is the code that I am using now:
Calling the methods from this class, The first method adds commas to the string and the second method checks if a comma is at the end when the user has finnished typing.
class BonusData
{
public class DoDataTextBox
{
public static void AutoComplete(TextBox textBox, int counter)
{
if (textBox.Text.Length - counter == 3)
{
textBox.Text = textBox.Text + ",";
textBox.SelectionStart = textBox.Text.Length;
}
else if (textBox.Text.Length - counter == 7)
{
textBox.Text = textBox.Text + ",";
textBox.SelectionStart = textBox.Text.Length;
}
else if (textBox.Text.Length - counter == 11)
{
textBox.Text = textBox.Text + ",";
textBox.SelectionStart = textBox.Text.Length;
}
}
public static void CheckLastCharacter(TextBox textBox)
{
if (textBox.Text.Length < 2) return;
if (textBox.Text.Substring(textBox.Text.Length - 1) != ",") return;
{
textBox.Text = textBox.Text.Substring(0, textBox.Text.Length - 1);
}
}
}
}
And the event handlers,
private void SecondMonthRowOne_OnKeyUp(object sender, KeyEventArgs e)
{
int counter = 0;
if (IsText)
{
counter = 1;
}
BonusData.DoDataTextBox.AutoComplete((TextBox)sender, counter);
}
private void SecondMonthRowOne_OnGotFocus(object sender, RoutedEventArgs e)
{
if (e.ToString() != String.Empty) return;
IsText = true;
}
private void SecondMonthRowOne_OnLostFocus(object sender, RoutedEventArgs e)
{
BonusData.DoDataTextBox.CheckLastCharacter((TextBox)sender);
IsText = false;
}
Which gives a result like this,
999,999,999
Like I said it works 98% of the time, but I was hoping there was another way to do this in WPF. I have searched far and wide, but I don't even know what something like this is called.
I suggest you to use "WPF TextBox AutoComplete" instead. It's a WPF attached behavior wrapped in a NuGet package.
You can simply add this package to your project by adding this using NuGet Package Manager for your WPF project.
This NuGet package is also open source, therefore you can customize it further to meet your needs/requirements.
The source code is hosted on this GitHub repo: https://github.com/Nimgoble/WPFTextBoxAutoComplete
NOTE: I haven't fully tested this WPF library against .NET 4.6. The library is compiled against .NET 4.5 as its target. But as far as I know, it's 100% compatible with WPF in .NET 4.6.
Without using any outside addins I found this to work really well,
This will add a Comma every third character and allow users to delete characters one at a time.
The TextBox format will look like this,
999,999,999,999
The code,
public class DoDataTextBox
{
public static void AutoCompleteStringBuild(TextBox textBox)
{
string endResult = null;
string replace = Reverse(textBox.Text).Replace(",", "");
int count = 1;
char[] value = replace.ToCharArray();
foreach (var car in value)
{
if (count % 3 == 0)
{
endResult = String.Concat(endResult, car);
if (value.Length != count)
{
endResult = String.Concat(endResult, ",");
}
count++;
}
else
{
endResult = String.Concat(endResult, car);
count++;
}
}
if (endResult == null) return;
string textBoxResult = Reverse(endResult);
textBox.Text = textBoxResult;
}
public static string Reverse(string stringVal)
{
char[] charArray = stringVal.ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}
public static void IsDeleteKey(TextBox textBox, KeyEventArgs e)
{
textBox.SelectionStart = e.Key == Key.Delete ? 0 : textBox.Text.Length;
}
}
And the event handler,
private void TextBoxOne_OnKeyUp(object sender, KeyEventArgs e)
{
BonusData.DoDataTextBox.AutoCompleteStringBuild((TextBox)sender);
BonusData.DoDataTextBox.IsDeleteKey((TextBox)sender, e);
}
At present this is the best way I have found to do this.
I'm trying to make 'find/find next' function in my windows store application.
Word which I want to search and select is in textBox named 'tboxFind'.
Textbox 'EditorWindow' contains all my text.
My function works good only if there is one line of text in 'editorWindow'.
Otherwise, selection is moved forwards by number of new lines.
How to fix it?
Is there any simple way to create find next function?
private void btnFind_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
if ((tmpPos) == pos && tmpWord == tboxFind.Text && !String.IsNullOrEmpty(editorWindow.Text))
{
string tmpString = editorWindow.Text.Substring(pos + tboxFind.Text.Length);
tmpPos = tmpString.ToLower().IndexOf(tboxFind.Text.ToLower());
if (tmpPos != -1)
{
editorWindow.Focus(Windows.UI.Xaml.FocusState.Keyboard);
editorWindow.SelectionStart = pos + tmpPos + tboxFind.Text.Length;
editorWindow.SelectionLength = tboxFind.Text.Length;
pos = pos + tmpPos + tboxFind.Text.Length;
}
}
tmpWord = tboxFind.Text;
tmpPos = pos;
}
// EDIT:
I found a different way to create that function. Here is my code:
private void btnFind_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
numOfNewLines = 0;
pos = (tmpWord == tboxFind.Text) ? editorWindow.Text.ToLower().IndexOf(tboxFind.Text, pos + tboxFind.Text.Length)
: editorWindow.Text.ToLower().IndexOf(tboxFind.Text);
if (pos != -1)
{
foreach (char s in editorWindow.Text.Substring(0, pos))
{
if (s == '\n')
{
numOfNewLines++;
}
}
pos -= numOfNewLines;
editorWindow.Focus(Windows.UI.Xaml.FocusState.Keyboard);
//tmpPos = editorWindow.Text.ToLower().IndexOf(tboxFind.Text);
editorWindow.Select(pos, tboxFind.Text.Length);
pos += numOfNewLines;
}
tmpWord = tboxFind.Text;
}
I'm not 100% sure what's wrong with your code because I can't fully replicate it, but consider the following SSCCE in a basic Windows application:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
foreach (var i in FindIndicies("text"))
{
this.textBox1.SelectionStart = i;
this.textBox1.SelectionLength = "text".Length;
var result = MessageBox.Show(
"Move to the next index?",
"Next?",
MessageBoxButtons.YesNo);
if (result == System.Windows.Forms.DialogResult.No) { break; }
}
}
private List<int> FindIndicies(string textToFind)
{
var indicies = new List<int>();
var offset = 0;
var i = 0;
while ((i = this.textBox1.Text.IndexOf(
textToFind,
offset,
StringComparison.CurrentCultureIgnoreCase)) > 0)
{
indicies.Add(i);
offset = (i + textToFind.Length);
}
return indicies;
}
}
given that textBox1 has a set text value of:
Here is a set of text
and I'm going to find the word text
Even when there are multiple lines of text.
It finds each index properly, and selects them properly.
I would consider finding all indicies up front with the method I wrote and then simply iterate through them on demand. In my case I'm using a message box to determine when I want to move to the next index, but you'll use something different.
I'm working on storing last used settings and then when program starts retrieve them back. Everything works fine but I just don't know how to deal with ListBox items.
To point out one thing is that I'm already using one delimiter to store my settings. I'm getting quite confused when dealing with this problem.
This is how I store my settings:
private void btnStart_Click(object sender, EventArgs e)
{
int interval = 0;
int plusMinus = 0;
int pause = 0;
int delay = 0;
int randomLine = 0;
if (cbPause.Checked == true) pause = 1;
if (cbDelay.Checked == true) delay = 1;
if (cbRandomLine.Checked == true) randomLine = 1;
interval = int.Parse(nudInterval.Value.ToString());
plusMinus = int.Parse(nudPlusMinus.Value.ToString());
lastUsed.Text =
interval + splitString +
plusMinus + splitString +
pause + splitString +
delay + splitString +
randomLine;
if (nudPlusMinus.Value == 0)
{
tmrInterval.Interval = int.Parse(nudInterval.Value.ToString());
}
else
{
Random random = new Random();
tmrInterval.Interval = random.Next(int.Parse(nudInterval.Value.ToString()) - int.Parse(nudPlusMinus.Value.ToString()), int.Parse(nudInterval.Value.ToString()) + int.Parse(nudPlusMinus.Value.ToString()));
}
WhenStarted();
tmrInterval.Start();
}
This is how I retrieve them at the program start up:
public AutoTyper()
{
InitializeComponent();
tmrInterval.Tick += new EventHandler(Interval);
tmrDelay.Tick += new EventHandler(Delay);
tmrSpace.Tick += new EventHandler(Space);
lbMessage.SelectedIndexChanged += new EventHandler(lbMessage_SelectedIndexChanged);
txtMessage.TextChanged += new EventHandler(txtMessage_TextChanged);
SetInterval();
if (!lastUsed.EmptyFile())
{
string[] allSettings = lastUsed.Text.Split(splitChar, StringSplitOptions.None);
int settingCount = 0;
int settingNumber = 0;
foreach (string setting in allSettings) settingNumber++;
if (settingNumber == 5)
{
foreach (string setting in allSettings)
{
settingCount++;
if (settingCount == 1) nudInterval.Value = int.Parse(setting);
else if (settingCount == 2) nudPlusMinus.Value = int.Parse(setting);
else if (settingCount == 3) { if (setting == "1") cbPause.Checked = true; }
else if (settingCount == 4) { if (setting == "1") cbDelay.Checked = true; }
else if (settingCount == 5) { if (setting == "1") cbRandomLine.Checked = true; }
}
}
}
}
Just retrieve/set SelectedIndex after adding all values (unless that happens at design time already).
But in general, I'd rewrite that settings handling. You should store your settings using keys and values. Otherwise you'll run into tons issue if you ever want to add, remove or change the order of some settings.
in a c# wpf application, Im loading a treeView from a list, it has a delete, edit, and add button used with information saved in a list from a textFile, it also has a update button which when clicked it clears the treeView and then reloads the textFile info into the list and then the lists into the treeView however whenever i click the update its crashes my file when it hits: treeView1.Items.Clear(); all the variables prior to the .Clear() lines at the start are lists, also the there are more if statements similar to this one if(i == 0) i just took them out cause they all work the same. Thanks
here is the event code for the updated button
private void buttonUpdate_Click(object sender, RoutedEventArgs e)
{
name.Clear();
description.Clear();
dateStart.Clear();
dateDue.Clear();
status.Clear();
priority.Clear();
details.Clear();
using (StreamReader sr = new StreamReader("TaskList.txt"))
{
int i = 0;
while (!sr.EndOfStream)
{
//if its on the first line of a task
if (i == 0)
{
name.Add(sr.ReadLine());
++i;
}
else if (i == 1)
{
description.Add(sr.ReadLine());
++i;
}
else if (i == 2)
{
dateStart.Add(sr.ReadLine());
++i;
}
else
{
details.Add(sr.ReadLine());
i = 0;
}
}
treeView1.Items.Clear();
for (int j = 0; j < name.Count; ++j)
{
TreeViewItem taskTree = new TreeViewItem();
taskTree.Tag = name[j];
taskTree.Header = name[j];
taskTree.Items.Add(description[j]);
taskTree.Items.Add(dateStart[j]);
taskTree.Items.Add(dateDue[j]);
taskTree.Items.Add(status[j]);
treeView1.Items.Add(taskTree);
}
sr.Close();
}
}
After clearing the treeview, SelectedItem is null.
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...