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();
Related
Dictionary<string, string> RoleName = new Dictionary<string, string>();
RoleName.Add("Admin", "toolStripMenuItem1.Enabled=true");
RoleName.Add("Manager", "toolStripMenuItem2.Enabled = true");
RoleName.Add("usero","btn.Enabled=true" );
RoleName.Add("customer", "btnorder.Enabled = true");
var t = contains the list of roles of the user in Database
foreach (var itemList in RoleName)
{
foreach (var itemdbRole in t)
{
if (itemList.Key == itemdbRole.Name)
{
CSharpCodeProvider cs = new CSharpCodeProvider(new Dictionary<string, string>());
CompilerParameters parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" });
parameters.GenerateExecutable = true;
CompilerResults results = cs.CompileAssemblyFromSource(parameters, itemList.Value); }
}
}
In the above code I want to execute the "value" in the dictionary list if it satisfied the conditions, I had used that code but it doesn't work, if anyone have better solution, as I want to execute the string in the dictionary's value as code, another issue using two for statements I think it consume more time any better way to check if the value of one list exists in the another list
Thank you in advance
You could store controls instead of strings in the dictionary:
Dictionary<string, Component> RoleName = new Dictionary<string, Component>
{
{ "Admin", toolStripMenuItem1 },
{ "Manager", toolStripMenuItem2 },
{ "user", btn },
{ "customer", btnorder }
};
// Disable all controls from the dictionary
toolStripMenuItem1.Enabled = false;
toolStripMenuItem2.Enabled = false;
btn.Enabled = false;
btnorder.Enabled = false;
var rolesFromDB = "Admin,user";
foreach (var role in rolesFromDB.Split(','))
{
if (RoleName.TryGetValue(role, out var component))
{
switch (component)
{
case ToolStripItem tItem:
tItem.Enabled = true;
break;
case Control control:
control.Enabled = true;
break;
}
}
}
Since the ToolStripItem doesn't inherit Control, we have to store controls as a Component in the dictionary.
I'm using .NET 2.0 and I'm trying to bind a combobox's Datasource to a sorted dictionary.
So the error I'm getting is "DataMember property 'Key' cannot be found on the Datasource".
SortedDictionary<string, int> userCache = UserCache.getSortedUserValueCache();
userListComboBox.DataSource = new BindingSource(userCache, "Key"); //This line is causing the error
userListComboBox.DisplayMember = "Key";
userListComboBox.ValueMember = "Value";
SortedDictionary<string, int> userCache = new SortedDictionary<string, int>
{
{"a", 1},
{"b", 2},
{"c", 3}
};
comboBox1.DataSource = new BindingSource(userCache, null);
comboBox1.DisplayMember = "Key";
comboBox1.ValueMember = "Value";
But why are you setting the ValueMember to "Value", shouldn't it be bound to "Key" (and DisplayMember to "Value" as well)?
I used Sorin Comanescu's solution, but hit a problem when trying to get the selected value. My combobox was a toolstrip combobox. I used the "combobox" property, which exposes a normal combobox.
I had a
Dictionary<Control, string> controls = new Dictionary<Control, string>();
Binding code (Sorin Comanescu's solution - worked like a charm):
controls.Add(pictureBox1, "Image");
controls.Add(dgvText, "Text");
cbFocusedControl.ComboBox.DataSource = new BindingSource(controls, null);
cbFocusedControl.ComboBox.ValueMember = "Key";
cbFocusedControl.ComboBox.DisplayMember = "Value";
The problem was that when I tried to get the selected value, I didn't realize how to retrieve it. After several attempts I got this:
var control = ((KeyValuePair<Control, string>) cbFocusedControl.ComboBox.SelectedItem).Key
Hope it helps someone else!
var colors = new Dictionary < string, string > ();
colors["10"] = "Red";
Binding to Combobox
comboBox1.DataSource = new BindingSource(colors, null);
comboBox1.DisplayMember = "Value";
comboBox1.ValueMember = "Key";
Full Source...Dictionary as a Combobox Datasource
Jeryy
userListComboBox.DataSource = userCache.ToList();
userListComboBox.DisplayMember = "Key";
A dictionary cannot be directly used as a data source, you should do more.
SortedDictionary<string, int> userCache = UserCache.getSortedUserValueCache();
KeyValuePair<string, int> [] ar= new KeyValuePair<string,int>[userCache.Count];
userCache.CopyTo(ar, 0);
comboBox1.DataSource = ar; new BindingSource(ar, "Key"); //This line is causing the error
comboBox1.DisplayMember = "Value";
comboBox1.ValueMember = "Key";
I know this is a pretty old topic, but I also had a same problem.
My solution:
how we fill the combobox:
foreach (KeyValuePair<int, string> item in listRegion)
{
combo.Items.Add(item.Value);
combo.ValueMember = item.Value.ToString();
combo.DisplayMember = item.Key.ToString();
combo.SelectedIndex = 0;
}
and that's how we get inside:
MessageBox.Show(combo_region.DisplayMember.ToString());
I hope it help someone
If this doesn't work why not simply do a foreach loop over the dictionary adding all the items to the combobox?
foreach(var item in userCache)
{
userListComboBox.Items.Add(new ListItem(item.Key, item.Value));
}
Use -->
comboBox1.DataSource = colors.ToList();
Unless the dictionary is converted to list, combo-box can't recognize its members.
Just Try to do like this....
SortedDictionary<string, int> userCache = UserCache.getSortedUserValueCache();
// Add this code
if(userCache != null)
{
userListComboBox.DataSource = new BindingSource(userCache, null); // Key => null
userListComboBox.DisplayMember = "Key";
userListComboBox.ValueMember = "Value";
}
I have a method (LoadCustomers()) that returns a dictionary of elements as follows:
Dictionary<int, string>()
I connected it to the datasource of a combobox like this:
Myclass m = new Myclass();
combo1.DataSource = new BindingSource(m.LoadCustomers(), null);
combo1.DisplayMember = "Value";
combo1.ValueMember = "Key";
Now I would like to put in front of the list of the combobox an item like:
<select one customer>
How to do this in c# on winforms?
Tks a lot
Add this option to the Dictionary of customers
const int EMPTYCUSTOMERKEY = -1; //be sure Customers will not contain this value
const string EMPTYCUSTOMERVALUE = "<select one customer>";
Myclass m = new Myclass();
Dictionary<int, string> customerSource = m.LoadCustomers();
customerSource.Add(EMPTYCUSTOMERKEY, EMPTYCUSTOMERVALUE);
combo1.DataSource = new BindingSource(customerSource, null);
combo1.DisplayMember = "Value";
combo1.ValueMember = "Key";
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 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();
}
}