I'm working on a windows phone project. I have a listbox with the following selectionchanged event handler:
private void judgeType_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
LoadJudgeCategories(judgeTypeListBox.SelectedItem.ToString());
}
Here is the LoadJudgeCategories method:
void LoadJudgeCategories(string judgeType)
{
string[] categories = judgeCategories[judgeType];
List<LabeledTextBox> itemSource = new List<LabeledTextBox>();
foreach (string cat in categories)
{
itemSource.Add(new LabeledTextBox(cat));
}
CategoryPanel.ItemsSource = itemSource;
}
judgeCategories is of type
Dictionary<string, string[]>
LabeledTextBox is usercontrol with a textblock and a textbox. CategoryPanel is just a listbox.
Whenever the selected item is changed, I want to clear CategoryPanel, and replace it with a new List.
Occasionally, however, when I change the selection, it gives the exception "value does not fall within the expected range".
How do I fix this?
This can happen when you add multiple controls with the same name. Try this code. Broken down with newlines for clarity. I turned it into a linq statement, and also named each of the LabeledTextBox something random.
Note: the only important thing I did was give the LabeledTextBox a name.
Random r = new Random();
void LoadJudgeCategories(string judgeType)
{
CategoryPanel.ItemsSource =
judgeCategories[judgeType]
.Select(cat =>
new LabeledTextBox(cat) { Name = r.Next().ToString() }
).ToList();
}
Just an alternative solution with ObservableCollection - there will be no need to set CategoryPanel.ItemsSource multiple times:
private ObservableCollection<LabeledTextBox> itemSource = new ObservableCollection<LabeledTextBox>();
CategoryPanel.ItemsSource = itemSource; // somewhere in the Constructor
void LoadJudgeCategories(string judgeType)
{
itemSource.Clear();
foreach (string cat in judgeCategories[judgeType])
itemSource.Add(new LabeledTextBox(cat));
}
Related
public Core()
{
InitializeComponent();
Archive.IntializeObjects();
Data.Load();
adultBox.DataSource = display;
}
void UpdateUI()
{
display.Clear();
foreach (Lesson l in lessons)
{
display.Add(l);
}
MessageBox.Show(lessons.Count.ToString());
adultBox.DisplayMember = "Title";
}
This method updates a separate list to filter from a larger list and then post it to a ListBox. Though the lessons list updates properly and contains multiple objects, only one item is ever shown in the box.
What am I missing?
Use this:
display.Items.Add(l);
or
display.Items.AddRange(l.ToArray());
I'm defining the MultiSelectListPreference in my axml file like this:
<MultiSelectListPreference
android:title="Title"
android:summary="Sum"
android:key="dutyMarks"
android:entries="#array/array_marks"
android:entryValues="#array/array_marksValues">
</MultiSelectListPreference>
How can check / read the checked boxes in code?
I tried to get the checked values via the PreferenceChange event:
The checked values appear there, but I have no idea how to get them...
This was also my first thought, but e.NewValue doesn't contain a public definition for 'GetEnumerator'.
We can simply cast e.NewValue from object to IEnumerable in our code, for example:
private void PreferenceChange(object sender, Preference.PreferenceChangeEventArgs e)
{
var selections = e.NewValue as IEnumerable;
if (selections != null)
{
foreach (var selection in selections)
{
Console.WriteLine(selection);
}
}
}
since e.NewValue is a HashSet, you should be able to iterate through it
foreach (string x in e.NewValue) {
// do whatever you need to do with each value x here
}
If someone stumbles across this question, here is how i solved it:
Read (the async part is pretty ugly, but I don't know how to add a 'preferenceChangeD' event)
private async void preferenceChange(object sender, Preference.PreferenceChangeEventArgs e)
{
await System.Threading.Tasks.Task.Delay(100);
List<string> sList = new List<string>();
ICollection<string> selectedValues = mslp_dutyMarks.Values;
foreach(string x in selectedValues)
sList.Add(x);
}
Write
mslp_dutyMarks.Values = new List<string> { "A", "B", "C" };
I need help with creating an ArrayList that adds words into a ComboBox, which then allows the user to click on the word and then it gets inserted into a RichTextBox. I do have the following code but it does not work. Hope someone could assist me please.
public partial class WordEditorApp : Form
{
//Creating an arraylist for the combobox.
ArrayList al = new ArrayList();
public WordEditorApp()
{
InitializeComponent();
//Initializing the radio buttons.
upperCase.Checked = false;
lowerCase.Checked = false;
//Adding items to the arraylist.
al.Add("Grams");
al.Add("Aristrocrats");
al.Add("Sophisticated");
al.Add("Corruption");
al.Add("Interrupt");
al.Add("Operation");
al.Add("Decision");
al.Add("Bantam");
al.Add("Brochure");
al.Add("Hydraulics");
al.Add("Properties");
//for loop to add items to the arraylist.
for (int i = 0; i < al.Count; i++)
{
comboBox1.Items.Add(al[i].ToString());
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
//Selected word from the combo box is appended into the textbox.
richTextBox1.AppendText(ArrayList.SelectedItem.ToString());
}
catch (Exception) { }
}
A simpler alternative
string[] al = { "Grams", "Aristrocrats", "Sophisticated", "Corruption", "Interrupt",
"Operation", "Decision", "Bantam", "Brochure", "Hydraulics", "Properties" };
comboBox1.Items.AddRange(al);
This is how I would do it:
Start by using current, efficient, type-safe and extensible objects and methods:
List<string> words = new List<string>()
{
"Grams", "Aristrocrats", "Sophisticated",
"Corruption", "Interrupt", "Operation",
"Decision", "Bantam", "Brochure", "Hydraulics", "Properties"
};
comboBox1.Items.AddRange(words.ToArray());
Then I would not append the text but set it as the SelectedText; this means the user can insert it anwhere, thus providing append, insert and replace all in one go:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
richTextBox1.SelectedText = comboBox1.SelectedItem.ToString();
}
Adding a space after each word may also be a friendly idea..
Note that if you only want to load a fixed number of items you can do it like this as well:
comboBox1.Items.AddRange(new[] { "Grams", "Aristrocrats", "Sophisticated",
"Corruption", "Interrupt", "Operation", "Decision",
"Bantam", "Brochure", "Hydraulics", "Properties" });
Here no local list or array is needed and the type is resolved from the values.
But if you declare a List<string> at class level you can expand it with new words the user enters and later store it in a file, creating a growing word list..
I thing this is wrong:
//Selected word from the combo box is appended into the textbox.
richTextBox1.AppendText(ArrayList.SelectedItem.ToString());
^
ArrayList doesnt have a static property called SelectedItem.
Did you mean comboBox1.SelectedItem.ToString(); ?
Try the below code.
richTextBox1.AppendText(comboBox1.Text);
You are trying to append text from ArrayList..
If you insist on ArrayList class (which is deprecated):
// static: you want just one instance for all WordEditorApp instances
private static ArrayList al = new ArrayList() {
"Grams",
"Aristrocrats",
"Sophisticated",
"Corruption",
"Interrupt",
"Operation",
"Decision",
"Bantam",
"Brochure",
"Hydraulics",
"Properties"
};
...
comboBox1.Items.AddRange(al.OfType<String>());
a better design is to change ArrayList to List<String> or String[]:
private static String[] al = new String[] {
"Grams",
"Aristrocrats",
...
"Properties"
};
...
// No need in OfType<String>() here
comboBox1.Items.AddRange(al);
I have a BindingList< KeyValuePair < string, string > > that is bound to a ComboBox control. Based on some conditions, the BindingList will be added a new KeyValuePair. Now, the Newly added item shows up at index 0 of the Combobox, instead of at the end.
While debugging, I found that the BindingList has got the right order. (i.e, the new KeyValuePair is appended)
Also, I check the SelectedValue of the ComboBox in it's SelectedIndexChanged handler and it seems to be not of the ListItem that got selected. Instead, it is that of the supposed ListItem, if the ComboBox had got the right order as in its DataSource, - the BindingList..
The code is a small part of a large project.. Plz let me know if the question is not clear. I can put the relevant parts of the code as per our context.
How could something like this happen? What can I do differently?
I have this class something like this.
public class DropdownEntity
{
//removed all except one members and properties
private string frontEndName
public string FrontEndName
{
get {return this.frontEndName; }
set {this.frontEndName= value; }
}
//One Constructor
public DropdownEntity(string _frontEndName)
{
this.FrontEndName = _frontEndName;
//Removed code which initializes several members...
}
//All methods removed..
public override string ToString()
{
return frontEndName;
}
}
In my windows form, I have a tab control with several tabs. In one of the tabs pages, I have a DataGridView. The user is supposed to edit the cells and click on a Next - button. Then, some processing will be done, and the TabControl will be navigated to the next tab page.
The next tab page has the combobox that has the problem I mentioned. This page also has a back button, which will take back.. the user can modify the gridview cells again.. and click on the next button. This is when the order gets messed up.
I am posting here the Click event handler of the Next Button.. Along with the class, with the rest of the code removed.
public partial class AddUpdateWizard : Form
{
//Removed all members..
BindingList<KeyValuePair<string, string>> DropdownsCollection;
Dictionary<string, DropdownEntity> DropdownsDict;
//Defined in a partial definition of the class..
DataGridView SPInsertGridView = new DataGridView();
ComboBox DropdownsCmbBox = new ComboBox();
Button NextBtn2 = new Button();
Button BackBtn3 = new Button();
//Of course these controls are added to one of the panels
public AddUpdateWizard(MainForm mainForm)
{
InitializeComponent();
DropdownsDict = new Dictionary<string, DropdownEntity>();
}
private void NextBtn2_Click(object sender, EventArgs e)
{
string sqlArgName;
string frontEndName;
string fieldType;
for (int i = 0; i < SPInsertGridView.Rows.Count; i++)
{
sqlArgName = "";
frontEndName = "";
fieldType = "";
sqlArgName = SPInsertGridView.Rows[i].Cells["InsertArgName"].Value.ToString().Trim();
if (SPInsertGridView.Rows[i].Cells["InsertArgFrontEndName"].Value != null)
{
frontEndName = SPInsertGridView.Rows[i].Cells["InsertArgFrontEndName"].Value.ToString().Trim();
}
if (SPInsertGridView.Rows[i].Cells["InsertArgFieldType"].Value != null)
{
fieldType = SPInsertGridView.Rows[i].Cells["InsertArgFieldType"].Value.ToString().Trim();
}
//I could have used an enum here, but this is better.. for many reasons.
if (fieldType == "DROPDOWN")
{
if (!DropdownsDict.ContainsKey(sqlArgName))
DropdownsDict.Add(sqlArgName, new DropdownEntity(frontEndName));
else
DropdownsDict[sqlArgName].FrontEndName = frontEndName;
}
else
{
if (fieldType == "NONE")
nonFieldCount++;
if (DropdownsDict.ContainsKey(sqlArgName))
{
DropdownsDict.Remove(sqlArgName);
}
}
}
//DropdownsCollection is a BindingList<KeyValuePair<string, string>>.
//key in the BindingList KeyValuePair will be that of the dictionary.
//The value will be from the ToString() function of the object in the Dictionary.
DropdownsCollection = new BindingList<KeyValuePair<string,string>>(DropdownsDict.Select(kvp => new KeyValuePair<string, string>(kvp.Key, kvp.Value.ToString())).ToList());
DropdownsCmbBox.DataSource = DropdownsCollection;
DropdownsCmbBox.DisplayMember = "Value";
DropdownsCmbBox.ValueMember = "Key";
//Go to the next tab
hiddenVirtualTabs1.SelectedIndex++;
}
private void BackBtn3_Click(object sender, EventArgs e)
{
hiddenVirtualTabs1.SelectedIndex--;
}
//On Selected Index Changed of the mentioned Combobox..
private void DropdownsCmbBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (DropdownsCmbBox.SelectedValue != null)
{
if (DropdownsDict.ContainsKey((DropdownsCmbBox.SelectedValue.ToString())))
{
var dropdownEntity = DropdownsDict[DropdownsCmbBox.SelectedValue.ToString()];
DropdownEntityGB.Text = "Populate Dropdowns - " + dropdownEntity.ToString();
//Rest of the code here..
//I see that the Datasource of this ComboBox has got the items in the right order.
// The Combobox's SelectedValue is not that of the selected item. Very Strange behavior!!
}
}
}
}
The very first time the user clicks the Next Button, it's fine. But if he clicks the Back Button again and changes the Data Grid View cells.. The order will be gone.
I know, it can be frustrating to look at. It's a huge thing to ask for help. Any help would be greatly appreciated!
Please let me know if you need elaboration at any part.
Thanks a lot :)
I think you have two problems here.
First, if you want to retain the order of the items you should use an OrderedDictionary instead of a regular one. A normal collection will not retain the order of the items when you use Remove method. You can see more info about this related to List here.
You could use such dictionary like this:
DropDownDict = new OrderedDictionary();
// Add method will work as expected (as you have it now)
// Below you have to cast it before using Select
DropDownCollection = new BindingList<KeyValuePair<string, string>>(DropDownDict.Cast<DictionaryEntry>().Select(kvp => new KeyValuePair<string, string>(kvp.Key.ToString(), kvp.Value.ToString())).ToList());
The second problem could be that you change the display name (FrontEndName) of already existing items, but the key is preserved. When you add a new item, try to remove the old one that you're not using anymore and add a new item.
The Sorted Property of the Combobox is set to True! I didn't check that until now. I messed up. Terribly sorry for wasting your time Adrian. Thanks a lot for putting up with my mess here.. :)
I have a method that adds items to my listbox called refreshInterface which is called as soon as the programe starts, adding names of homeforms in the listbox using the FormItems class, here is the rereshInterface method below
public void refreshInterface()
{
//int number = 0;
foreach (DataSet1.xspGetAnalysisUsageTypesRow homeForms in myDataSet.xspGetAnalysisUsageTypes)
{
var forms = new FormItems(homeForms);
listBox1.Items.Add(forms);
}
}
The FormItems class is this below
public class FormItems
{
public DataSet1.xspGetAnalysisUsageTypesRow types { get; set; }
public FormItems(DataSet1.xspGetAnalysisUsageTypesRow usageTypes)
{
types = usageTypes;
}
public override string ToString()
{
// returns the rows that are relating to types.xlib_ID
var libtyps = types.GetxAnalysisUsageRows();
var cnt = 0;
foreach (DataSet1.xAnalysisUsageRow ty in libtyps)
{
//returns true if ty is null
bool typeNull = ty.Isxanu_DefaultNull();
// if its false, if xanu_Default is set
if (!typeNull)
{
cnt += 1;
}
}
var ret = String.Format("set {0} [Set: {1}]", types.xlib_Desc, cnt);
//return this.types.xlib_Desc;
return ret;
}
}
Each listbox (the listbox is on the left of the homeform) item has a number of reports that can be added to it, so for instance, i select an homeform from my listbox, there are 12 textboxes on the right hand side and each textbox has a pair of buttons which are Browse and Clear. If I click on the browse button a new form appears, and i select a report from that form and add it to a particular textbox, the count for that homeform should update, and i clear a textbox for a particular homeform, the count should also update.
At the moment when i debug the application, it shows me the count of each Homeform depending on the amount of reports added to the homeform, but while the programe is running, if i add a new report to a homeform, the count does not update until i restart the debug session. I was told about using a Databinding method but not sure of how i could use it here
How do i ge my listbox item to update ?
You should probably look into binding. Here is a good place to start:
http://www.codeproject.com/Articles/140621/WPF-Tutorial-Concept-Binding
If you want a GUI to respond to data changes then binding is your best friend.
You should bind List Box component source to Observable Collection, every update you do to Observable Collection will update List Box data.
Might not be exact but should give you an idea.
public void refreshInterface()
{
Dictionary<int,string> items = new Dictionary<int,string>();
//int number = 0;
foreach (DataSet1.xspGetAnalysisUsageTypesRow homeForms in myDataSet.xspGetAnalysisUsageTypes)
{
var formitem = new FormItems(homeForms);
items.Add(formitem.someprop, formitem.toString());
}
listbox.DataSource = items;
listbox.DisplayMember = "Value";
listbox.ValueMember = "Key";
}