I have an empty listbox on .aspx page
lstbx_confiredLevel1List
I am generating two lists programatically
List<String> l1ListText = new List<string>(); //holds the text
List<String> l1ListValue = new List<string>();//holds the value linked to the text
I want to load lstbx_confiredLevel1List list box on .aspx page with above values and text. So i am doing following:
lstbx_confiredLevel1List.DataSource = l1ListText;
lstbx_confiredLevel1List.DataTextField = l1ListText.ToString();
lstbx_confiredLevel1List.DataValueField = l1ListValue.ToString();
lstbx_confiredLevel1List.DataBind();
but it does not load the lstbx_confiredLevel1List with l1ListText and l1ListValue.
Any ideas?
Why don't you use the same collection as DataSource? It just needs to have two properties for the key and the value. You could f.e. use a Dictionary<string, string>:
var entries = new Dictionary<string, string>();
// fill it here
lstbx_confiredLevel1List.DataSource = entries;
lstbx_confiredLevel1List.DataTextField = "Value";
lstbx_confiredLevel1List.DataValueField = "Key";
lstbx_confiredLevel1List.DataBind();
You can also use an anonymous type or a custom class.
Assuming that you have already these lists and you need to use them as DataSource. You could create a Dictionary on the fly:
Dictionary<string, string> dataSource = l1ListText
.Zip(l1ListValue, (lText, lValue) => new { lText, lValue })
.ToDictionary(x => x.lValue, x => x.lText);
lstbx_confiredLevel1List.DataSource = dataSource;
You'd better used a dictionnary:
Dictionary<string, string> list = new Dictionary<string, string>();
...
lstbx_confiredLevel1List.DataSource = list;
lstbx_confiredLevel1List.DataTextField = "Value";
lstbx_confiredLevel1List.DataValueField = "Key";
lstbx_confiredLevel1List.DataBind();
Unfortunately the DataTextField and DataValueField are not used like that. They are the text representation of the fields they're supposed to show of the current item that's being databound in the DataSource.
If you had an object that held both text and value, you'd make a list of it and set that to datasource like this:
public class MyObject {
public string text;
public string value;
public MyObject(string text, string value) {
this.text = text;
this.value = value;
}
}
public class MyClass {
List<MyObject> objects;
public void OnLoad(object sender, EventArgs e) {
objects = new List<MyObjcet>();
//add objects
lstbx.DataSource = objects;
lstbx.DataTextField = "text";
lstbx.DataValueField = "value";
lstbx.DataBind();
}
}
Related
Here is my dictionary with strings and actions defined
SortedDictionary<string, Action> buttonoptions = new SortedDictionary<string, Action>
{
{"Left Click", DoMouseClick()},
{"Right Click", DoRightMouseClick()},
{"Windows Key", wKey()}
};
abuttonCombo.DataSource = new BindingSource(buttonoptions, null);
abuttonCombo.DisplayMember = "Key";
abuttonCombo.ValueMember = "Value";
And here is where i want to run the relevant action:
if (stateOld.Gamepad.Buttons != GamepadButtonFlags.A && stateNew.Gamepad.Buttons == GamepadButtonFlags.A)
{
//run the relevant action from the comboBox.SelectedValue
}
How would i accomplish this?
First, make sure you create Action within the SortedDictionary with new Action.
SortedDictionary<string, Action> buttonoptions = new SortedDictionary<string, Action>
{
{"Left Click", new Action(DoMouseClick)},
{"Right Click", new Action(DoRightMouseClick)},
{"Windows Key",new Action(wKey)}
};
comboBox1.DataSource = new BindingSource(buttonoptions, null);
comboBox1.DisplayMember = "Key";
comboBox1.ValueMember = "Value";
Create the methods DoMouseClick, DoRightMouseClick and wKey, each returning void.
private void wKey()
{
}
private void DoRightMouseClick()
{
}
private void DoMouseClick()
{
}
Finally, you can use dynamic to get the Action and run it. Make sure you use SelectedItem and not SelectedValue.
dynamic selection = comboBox1.SelectedItem;
var selectionMethod = selection.Value;
selectionMethod();
C# / Winforms program.
I have the following class which contains my dictionaries:
public class DictionaryInit
{
public Dictionary<int, DictionaryCheckup> C = new Dictionary<int, DictionaryCheckup>()
{
{1000, new DictionaryCheckup {theGrouping="C"}},
{100, new DictionaryCheckup {theGrouping="C"}},
};
}
Where DictionaryCheckup is a class that get;sets; a string theGrouping.
In the class, I would have letters from C to T, and I wanted to display their values within a combo box. This is what I've tried:
var theDictionaries = new DictionaryInit();
List<Dictionary<int, DictionaryCheckup>> Dictionaries = new List<Dictionary<int, DictionaryCheckup>> { theDictionaries.C, etc };
cmbDictionList.DataSource = new BindingSource(Dictionaries, null);
Running this fills the box with [Collection].
The process and desired outcome:
The idea is that, the user first selects a dictionary (C-T) from the combo box and the value gets saved to a variable. I then have the following code that will make use of this:
OFD.ShowDialog();
var theDict = new DictionaryInit();
if (OFD.FileName != null)
{
using (var stream = new StreamReader(File.OpenRead(OFD.FileName)))
{
// Read our JSON from the file
var json = stream.ReadToEnd();
theDict.E = JsonConvert.DeserializeObject<Dictionary<int, DictionaryCheckup>>(json);
var files = new Dictionary<string, Dictionary<int, DictionaryCheckup>>();
}
}
As you can see in my current process, I am explicitly declaring theDict.E. I wish to be able to replace it with a variable I picked up from the combo box earlier, so that I may choose which dictionary I serialize / deserialize.
I want to be able to somehow use my DictionaryInit class as the datasource of the combo box.
The value selected will determine the dictionary I will serialize in a later method.
If all DictionaryCheckup inside DictionaryInit.C have the same letter I would do it like this:
Add Letter property to DictionaryInit
Bind ComboBox to List
Set ComboBox's DisplayMember = "Letter"
Code:
public class DictionaryInit
{
public string Letter { get; private set; }
public DictionaryInit(string letter)
{
this.Letter = letter;
C = new Dictionary<int, DictionaryCheckup>()
{
{1000, new DictionaryCheckup {theGrouping=letter}},
{100, new DictionaryCheckup {theGrouping=letter}},
};
}
public Dictionary<int, DictionaryCheckup> C { get; private set; }
}
var list = new List<DictionaryInit>();
list.AddRange(new[]{new DictionaryInit("C"), new DictionaryInit("D")});
cmbDictionList.DataSource = list;
cmbDictionList.DisplayMember = "Letter";
I currently have a dictionary which contains a key value and a list associated with that key.
I have read How to bind Dictionary to ListBox in winforms and when I try to implement that it just displays the key value.
What I am trying to do is have two separate listboxs. In box 1 you select the key value, when this happens box 2 displays the list. The current code is below:
var xmlDoc2 = new XmlDocument();
xmlDoc2.Load(textBox1.Text);
Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
var node = xmlDoc2.SelectNodes("pdml/packet/proto[#name='ip']/#showname");
foreach (XmlAttribute attribute1 in node)
{
string ip = attribute1.Value;
var arr = ip.Split(); var src = arr[5]; var dst = arr[8];
List<string> l;
if (!dict.TryGetValue(src, out l))
{
dict[src] = l = new List<string>();
}
l.Add(dst);
listBoxSRC.DataSource = new BindingSource(dict, null);
listBoxSRC.DisplayMember = "Value";
listBoxSRC.ValueMember = "Key";
}
What this does so far is displays the key value in listBoxSRC, which is fine. What I need to do is display the list in listBoxDST.
I also looked at using ListView to rectify this issue but I couldn't figure out how it worked.
I know there should be a listBoxSRC_SelectedIndexChange somewhere but I keep getting 'dict doesn't appear in this context' errors.
Thanks
I jotted up something real quick with a pair of list boxes. Just make any form with a pair listboxes in it and wire up the event to try it yourself. By using the SelectedItem and casting it as the KeyValuePair that it is, you don't have to declare that dictionary outside of the method scope, as shown below.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
listBox1.DataSource = new BindingSource(new Dictionary<string, List<string>>
{
{"Four-Legged Mammals", new List<string>{"Cats", "Dogs", "Pigs"}},
{"Two-Legged Mammals", new List<string>{"Humans", "Chimps", "Apes"}}
}, null);
listBox1.DisplayMember = "Value";
listBox1.ValueMember = "Key";
}
private void listBox1_SelectedValueChanged(object sender, EventArgs e)
{
if (listBox1.SelectedItem != null)
{
var keyValue = (KeyValuePair<string, List<String>>) listBox1.SelectedItem;
listBox2.DataSource = keyValue.Value;
}
else
{
listBox2.DataSource = null;
}
}
I am creating a new window called AMTI which is using comboboxes to display different selections for the user. The selection text could for example be "Analytical", in which case the value "E04" should be stored in appropriate column in the AMTI-table in the database. I read about using enums for databinding, but here a text and a numeric value are tied together, which can then be databound in the combobox. What is the easiest (or correct) approach for mapping a display text in a combobox with a value to be stored in the database?
You can bind ComboBox to any collection which elements expose public properties, including datatable, or, if you don't have a collection ready and need key-value objects, you can use Dictionary.
Dictionary<string, int> dict = new Dictionary<string, int>();
// fill the dictionary here
mycomboBox.DataSource = new BindingSource(dict, null);
mycomboBox.DisplayMember = "Key";
mycomboBox.ValueMember = "Value";
if(mycomboBox.SelectedIndex!=-1)
int currentlySelected = (int)mycomboBox.SelectedValue;
... or make your own class of objects for binding:
class NameValueHolder
{
public string Name{get;set;}
public int Value{get;set;}
public NameValueHolder(){}//so you can use it in linq
public NameValueHolder(string name, int value)
{
this.Name=name;
this.Value=value;
}
}
BindingList<NameValueHolder> list = new BindingList<NameValueHolder>();
list.Add(new NameValueHolder("object 1", 1);
list.Add(new NameValueHolder("object 2", 2);
list.Add(new NameValueHolder("object 3", 3);
mycomboBox.DataSource = new BindingSource(list, null);
mycomboBox.DisplayMember = "Name";
mycomboBox.ValueMember = "Value";
if(mycomboBox.SelectedIndex!=-1)
NameValueHolder currentlySelected = (NameValueHolder)mycomboBox.SelectedValue;
You can also bind ComboBox to Linq query result:
var qResult = from a in yourDataSource
where (/*some condition*/)
select new {Name = a.someName, Value = a.someValue};
mycomboBox.DataSource = qResult.ToList();
mycomboBox.DisplayMember = "Name";
mycomboBox.ValueMember = "Value";
Those are just some of the posibilities.
In a Windows Form application, I'm trying to create a DataGridView with two columns: one for the key given by an XML element and one for the value of said XML element. This is my code so far:
this.myData = new DataGridView();
((System.ComponentModel.ISupportInitialize)(myData)).BeginInit();
myData.Location = new System.Drawing.Point(12, 42);
myData.Name = "myData";
myData.Size = new System.Drawing.Size(1060, 585);
myData.TabIndex = 32;
foreach (XElement xElem in xInfoItems)
{
numItems++;
}
myData.Columns.Add(new DataGridViewTextBoxColumn());
myData.Columns.Add(new DataGridViewTextBoxColumn());
myData.Columns[0].Name = "Key";
myData.Columns[0].DataPropertyName = "key";
myData.Columns[1].Name = "Value";
myData.Columns[1].DataPropertyName = "value";
List<myRow> data = new List<myRow>();
foreach (XElement xElem in xInfoItems)
{
data.Add(new myRow(xElem.Attribute("key").Value, xElem.Value));
}
myData.DataSource = data;
myData.Refresh();
this.PerformLayout();
I have confirmed that all of the information in data is being loaded via foreach, so that part is working. My problem is that the grid displays, but nothing shows up on the grid. What am I doing wrong? I'm not very good with this data type so I apologize if it's something obvious.
UPDATE
I figured out that I hadn't set myData up properly in the Design view. After adding the myRow class, it worked perfectly. Thanks for the help!
The problem may lie in your myRow class. When I was trying to reproduce your code, I first defined "key" and "value" as public fields of the myRow class as so:
public class myRow {
public string key;
public string value;
public myRow( string Key, string Value )
{
key = Key;
value = Value;
}
}
This caused the bound rows to show up but the text was not in the cells. When I changed both of them to properties, the binding worked much better:
public class myRow{
private string _key;
public string key
{
get
{
return _key;
}
}
private string _value;
public string value
{
get
{
return _value;
}
}
public myRow( string Key, string Value )
{
_key = Key;
_value = Value;
}
}
Probably the modifications I made on your code can help. (I just have focused on the part where you create the columns and add the rows, using a DataTable).
this.myData = new DataGridView();
((System.ComponentModel.ISupportInitialize)(myData)).BeginInit();
myData.Location = new System.Drawing.Point(12, 42);
myData.Name = "myData";
myData.Size = new System.Drawing.Size(1060, 585);
myData.TabIndex = 32;
foreach (XElement xElem in xInfoItems)
{
numItems++;
}
// Here we create a DataTable with two columns.
DataTable table = new DataTable();
table.Columns.Add("Key", typeof(string));
table.Columns.Add("Value", typeof(string));
foreach (XElement xElem in xInfoItems)
{
//Here we add rows to table
table.Rows.Add(xElem.Attribute("key").Value, xElem.Value);
}
myData.DataSource = table;
myData.Refresh();
this.PerformLayout();