Confused about about how to iterate this collection - c#

What I want to do is get all available network adapters
with key and value pairs.So I have class named Adapters consist of two variable first one is to keep
registry key and the second one is to
keep Adapter name such as (wireless ,local area and so on).And this is my code
List<Adapters> GetAdapterNames(string regPath)
{
List<Adapters> list = new List<Adapters>();
RegistryKey key = RootNode(regPath, false);
if (key != null)
{
string[] par = key.GetSubKeyNames();
foreach (string node in par)
{
if (node != "Descriptions")
{
RegistryKey keys = RootNode(regPath+"\\"+node + "\\Connection", false);
string name = keys.GetValue("Name").ToString();
list.Add(new Adapters(name,node));
}
}
return list;
And this is my adapterclass
class Adapters
{
private string _name;
private string _val;
public string Name
{
get { return _name; }
set { _name = value; }
}
public string Val
{
get { return _val; }
set { _val = value; }
}
public Adapters(string name,string value)
{
_name = name;
_val = value;
}
}
The problem is how can I give this list to the combobax and loop through in it .
something like this
private const string ADAPTER_PATH =
#"SYSTEM\ControlSet001\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
List<Adapters>adapters= GetAdapterNames(ADAPTER_PATH);
combobax.valueMember=//list.name
combobax.displayMember=list.node;
}

Based on the example you've got (please see How to create a Minimal, Complete, and Verifiable example for advice on how to provide a good code example in your question), the following would work:
private void Form1_Load(object sender, EventArgs e)
{
List<Adapters>adapters= GetAdapterNames(ADAPTER_PATH);
combobax.DataSource = adapters;
combobax.ValueMember = "Name";
combobax.DisplayMember = "Val";
}
You can assign any implementation of IList to the DataSource property of the ComboBox.
The ValueMember and DisplayMember properties can be used to control what value is returned from the SelectedValue property and what string is displayed in the ComboBox itself, respectively. They are string values which contain the name of a property of the class of the objects used to populate the ComboBox.
Notes:
I have no idea if combobax is in fact the correct name for the field in your form that contains the reference to the ComboBox object. That's what you typed, so it's what I've left here.
It seems a little odd to display the node registry key name, and use the "friendly" adapter name as the value member. But again, that's what you typed, so that's what I've shown in the example.

Related

C# populate a combo box from a method

What I would like to do is to populate a drop down menu from a database.
First of all I plan to use a combo box.
I have created an object that contains the data that I need to take from the database. The object is as follows
namespace RLMD
{
public class FlashCardLevel
{
private int intFCLId;
private String strFCLName;
public FlashCardLevel(int intFCLId, String strFCLName)
{
this.intFCLId = intFCLId;
this.strFCLName = strFCLName;
}
public int IntFCLId
{
get { return intFCLId; }
set { this.intFCLId = value; }
}
public String StrFCLName
{
get { return strFCLName; }
set { this.strFCLName = value; }
}
}
}
What I need to do is to add a list of items from a database, but for ease of use I have simulated given some sample data.
public List<FlashCardLevel> Rifle(List<FlashCardLevel> fcLevel)
{
fcLevel.Add(new FlashCardLevel(1, "Severe"));
fcLevel.Add(new FlashCardLevel(2, "Moderate"));
fcLevel.Add(new FlashCardLevel(3, "Mild"));
fcLevel.Add(new FlashCardLevel(4, "Slight"));
return fcLevel;
}
I'm calling the method here.
List<FlashCardLevel> fcLevel = new List<FlashCardLevel>();
talkToDatabase.Rifle(fcLevel);
this.comboCardLevel.DataSource = fcLevel;
this.comboCardLevel.DisplayMember = "Name";
this.comboCardLevel.ValueMember = "Value";
The combobox is displaying no information.
I would appreciate any help
Updated:
The DisplayMember Property should be referring to FlashCardLevel (class), Property StrFCLName and ValueMember should be pointing to IntFCLId.
List<FlashCardLevel> fcLevel = new List<FlashCardLevel>();
talkToDatabase.Rifle(fcLevel);
this.comboCardLevel.DataSource = listFromDatabase;
this.comboCardLevel.DisplayMember = "StrFCLName";
this.comboCardLevel.ValueMember = "IntFCLId";
The DisplayMember and ValueMember should point to your properties name.
this.comboCardLevel.DisplayMember = "IntFCLId";
this.comboCardLevel.ValueMember = "StrFCLName";

Wp7 ListBox ItemSource ObservableCollection IndexOUtofRange and Items are not updated

I have the following issue: I am creating a Windows Phone 7 application and I am using a ListBox which is bound to an ObservableCollection people. The implementation of this you see below:
public class Person
{
private string _id { get; set; }
private string _name { get; set; }
public Person(string Id, string Name, string Title)
{
_id = Id;
_name = Name;
}
public string Id
{
get { return _id; }
set
{
_id = value;
FirePropertyChangedEvent("Id");
}
}
public string Name
{
get { return _name; }
set
{
_name = value;
FirePropertyChangedEvent("Name");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void FirePropertyChangedEvent(string propertyName)
{
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
The people Collection is filled with Person objects. They are created in the following function... listValues is my ListBox.
void svc_GetHierachyCompleted(object sender, HCMobileSvc.GetHierachyCompletedEventArgs e)
{
var data = e.Result.ToArray();
listValues.ItemsSource = null;
people.Clear();
int i = 0;
foreach(var item in data)
{
if (i == 0)
{
// Manager
mgrField1.Text = item[1].ToString();
mgrField2.Text = item[2].ToString();
i++;
}
else
{
// Untergebenen hinzufügen
people.Add(new Person(item[0].ToString(), item[1].ToString(), item[2].ToString()));
}
}
// Update List
listValues.ItemsSource = people;
}
Now I have a DataTemplate with two textblocks bound to both properties Id and Name. When the SelectionChanged event is fired I try to rebuild the entire list (so I call the function above again) using the following code:
string id = people[listValues.SelectedIndex].Id;
MessageBox.Show(id);
CreateHierachy(id);
The CreateHierachy just only queries a WebService which then goes into the method above. The problem is, as soon as I select a value in the ListBox I get the following error:
ArgumentOutOfRangeException {"\r\nParameter name: index"}
The error is caused by the line listValues.SelectedIndex.
I absolutely have no idea why that happens. What I know is that the MessageBox shows me the correct SelectedIndex value. What I also know is that when I remove the line people.Clear() that the error goes away but the ListBox does not get Updated.
Any ideas where the problem might be?
Thanks!!!
Bye,
WorldSignia
You should check here for SelectedIndex being >= 0:
if (listValues.SelectedIndex >= 0)
string id = people[listValues.SelectedIndex].Id;

Unable to edit values in a DataGridView (using BindingList)

It seems that, due to an unknown cause, I am now unable to edit anything in my DataGridView. The DGV's ReadOnly property value is false, and all columns except for one all have the ReadOnly property set to false as well.
I'm beginning to think that it may be due to a special value I tried adding to one of my classes, one that I only wanted to be modified within the class, but still read only to the public. I don't think that value is messing with anything else, but none the less, here is the relevant portion of my code:
private void loaderWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
loadingBar.Value = e.ProgressPercentage;
if (e.UserState != null)
{
savefiles.Add((SaveFile)e.UserState);
}
}
Where savefiles is a BindingList, and where SaveFile is my class:
public class SaveFile
{
private string d_directory;
private int d_weirdnumber;
private bool d_isautosave;
private string d_fullname;
private string d_datatype;
private string d_owner;
private bool d_isquicksave;
private string d_title;
private string d_gametime;
public SaveFile() { }
public SaveFile(string directory, int weirdnumber, bool isautosave, string fullname, string datatype, string owner, bool isquicksave, string title)
{
d_directory = directory;
d_weirdnumber = weirdnumber;
d_isautosave = isautosave;
d_fullname = fullname;
d_datatype = datatype;
d_owner = owner;
d_isquicksave = isquicksave;
d_title = title;
}
public string Gametime
{
get { return d_gametime; }
}
public string Datatype
{
get { return d_datatype; }
set { d_datatype = value; }
}
public string Title
{
get { return d_title; }
set { d_title = value; }
}
public bool IsQuickSave
{
get { return d_isquicksave; }
set { d_isquicksave = value; }
}
public bool IsAutoSave
{
get { return d_isautosave; }
set { d_isautosave = value; }
}
public string Directory
{
get { return d_directory; }
set { d_directory = value; }
}
public string FullName
{
get { return d_fullname; }
set
{
d_fullname = value;
string[] split = value.Split(new char[]{'-'});
foreach (string str in split)
{
if (System.Text.RegularExpressions.Regex.IsMatch(str, "^\\d\\d:\\d\\d:\\d\\d$"))
{
d_gametime = str;
}
}
}
}
public int Weirdnumber
{
get { return d_weirdnumber; }
set { d_weirdnumber = value; }
}
public string Owner
{
get { return d_owner; }
set { d_owner = value; }
}
}
Gametime is that special property I mentioned earlier. It doesn't have a set function, but according to this, I should be in the clear, right?
Can anyone then tell me why I may not be able to edit any of the DGV cells?
EDIT: I just found out that not setting AutoGenerateColumns to false allows me to edit again, but I still don't know why.
After several hours, a friend finally took a look at it over Remote Desktop. He wrote a function to force all columns to have a non read-only status, and go figure, it worked. So we looked at the column properties in the editor, and somehow... I don't know why... they were all set to Read only. I swear I checked them 4 times before.
The lesson of this story (I guess): When in doubt, check your settings. When not in doubt, become doubtful. Otherwise, file a bug report to Microsoft :\

C# combobox overridden ToString

I am experiencing some problems while working with ComboBox.
The display member for my combobox is not being populated by the overridden ToString method of class MAP.
Here is my code:
Form1.cs:
private void Form1_Load(object sender, EventArgs e) {
...
...
MAPList MAP = new MAPList();
comboBox1.DataSource = MAP.All;
comboBox1.ValueMember = "Code";
...
...
}
MAPList.cs:
public class MAPList {
public readonly List<MAP> All;
public MAPList() {
All = new List<MAP>();
var MapData = // Getting map data
foreach(MAP m in MapData) {
All.Add(new Map(m.Name, m.Code));
}
}
}
MAP.cs:
public class MAP {
public readonly string Name;
private string code;
public string Code { get { return code; } }
public RadioCode(string Name, string Code) {
this.Name = Name;
this.code = Code;
}
public override string ToString() {
return String.Format("{0}: {1}", Name, Code);
}
}
ToString will not be called if you set ValueMember. If you do not set ValueMember it will work as expected but then of course Code will not be used as the selected value of the ComboBox.
Alternatively, if you wish to use ValueMember you may also want to set DisplayMember. You can create a property on your MAP that is used for display, i.e.:
public class MAP
{
public readonly string Name;
private string code;
public string Code { get { return code; } }
public string Display { get { return ToString(); } }
public MAP(string Name, string Code)
{
this.Name = Name;
this.code = Code;
}
public override string ToString()
{
return String.Format("{0}: {1}", Name, Code);
}
}
In the form you can then set DisplayMember:
MAPList MAP = new MAPList();
comboBox1.DataSource = MAP.All;
comboBox1.ValueMember = "Code";
comboBox1.DisplayMember = "Display";
This is because you've set your ValueMember property to "Code", so the values in the combobox are not your Map objects but rather the strings corresponding to their Code properties.
If you remove this line:
comboBox1.ValueMember = "Code";
...it will work as you expect.
If you want the ComboBox to display its items according to your Map type's ToString method, then Jakob's answer is right on: create a property on your Map type that provides a string formatted exactly how you want it, and set the DisplayMember property of the ComboBox to the name of this property.
this could be because u r using ValueMember. use DisplayMember Property, add another property on the Map class in the get of this property return the formatted string.
I know this is an old post, but if someone wants to use ToString() without creating a property to just call ToString(), you'll have to explicitly set the DisplayMember value to an empty string like this:
Form1.cs:
private void Form1_Load(object sender, EventArgs e) {
...
...
MAPList MAP = new MAPList();
comboBox1.DataSource = MAP.All;
comboBox1.ValueMember = "Code";
comboBox1.DisplayMember = ""; // Explicitly set it to an empty String
...
...
}

Proper way to map combo box lines to their corresponding strategy objects?

I have a situation that is pretty simple, and I'd like to know the ideal way to do it.
I have a combo box. Each line of the combo box corresponds to a particular strategy object.
What is the proper way to map the combo box lines to the strategy object.
The way I was doing it seems overly complicated, and I'm pretty much guaranteed there is a simple standard way to do this.
Thank you.
EDIT:
I had the data in a Dictionary, where the string was the text for the combobox, and the object was the strategy... But this isn't ordered... And I just know there is some extremely simple way to do it.
SOLUTION:
I used this solution, not feeling comfortable putting presentation logic in the data classes:
private partial class HtmlTransformState : AbstractHtmlEditFormState
{
private Dictionary<string, ITransformStrategy> strategies = new Dictionary<string, ITransformStrategy>()
{
{ "Simple URL", new TransformStrategy<SimpleUrlCodeExtractor>() },
{ "Overview", new TransformStrategy<OverviewCodeExtractor>() },
{ "Video List", new TransformStrategy<VideoListCodeExtractor>() },
{ "Video List No MbORKb", new TransformStrategy<VideoListNoMBOrKBAndNoLinksAllowedCodeExtractor>() },
{ "Blue Mountain 2007", new TransformStrategy<BlueMountain2007CodeExtractor>() },
{ "Four Gates", new TransformStrategy<FourGatesCodeExtractor>() },
{ "General", new TransformStrategy<GeneralCodeExtractor>() }
};
public override void DrawForm()
{
// ...
ParentForm.cmboTransformStrategy.DataSource = new BindingSource(strategies, null);
ParentForm.cmboTransformStrategy.DisplayMember = "Key";
ParentForm.cmboTransformStrategy.ValueMember = "Value";
}
public override IEnumerable<string> ProcessHtml(string urlPath)
{
ITransformStrategy transformStrategy = (ITransformStrategy)ParentForm.cmboTransformStrategy.SelectedValue;
// Do some stuff with 'transformStrategy'
}
}
Do you mean something like the following?
public class Strategy
{
private string _name = "default";
public string Name
{
get { return _name; }
set { _name = value; }
}
public Strategy(string name)
{
_name = name;
}
}
Then in form load (you need to have a combo box on that form):
private void Form1_Load(object sender, EventArgs e)
{
List<Strategy> ls = new List<Strategy>();
ls.Add(new Strategy("First"));
ls.Add(new Strategy("Second"));
ls.Add(new Strategy("Third"));
comboBox1.DataSource = ls;
comboBox1.DisplayMember = "Name";
}
Override ToString for your strategy object. After that you can insert your strategy objects directly in the combo box.
public class StrategyObject
{
public override string ToString()
{
return "return the text to display";
}
}
StrategyObject selectedStratObj = comboBox1.SelectedItem as StrategyObject;
I would use the SelectedIndexChanged event on the combobox and select the corresponding dictionary entry
found that, Bind a Dictionary to a ComboBox see below for a working example(at least on the original vb.net code that I wrote)
Vb.net converted into C#, you will have to manage the handle yourself
public class Form1
{
private Dictionary<int, myDic> dict = new Dictionary<int, myDic>();
private void // ERROR: Handles clauses are not supported in C#
ComboBox1_SelectedIndexChanged(System.Object sender, System.EventArgs e)
{
KeyValuePair<int, myDic> curItem = (KeyValuePair<int, myDic>)ComboBox1.SelectedItem;
MessageBox.Show(curItem.Value.myvalue);
}
private void // ERROR: Handles clauses are not supported in C#
Form1_Load(object sender, System.EventArgs e)
{
myDic d = default(myDic);
for (int i = 0; i <= 10; i++) {
d = new myDic();
d.myKey = i.ToString;
d.myvalue = Strings.Chr(65 + i);
dict.Add(d.GetHashCode, d);
}
ComboBox1.DataSource = new BindingSource(dict, null);
ComboBox1.DisplayMember = "value";
ComboBox1.ValueMember = "Key";
}
}
class myDic
{
public string myKey;
public string myvalue;
public override string tostring()
{
return myvalue;
}
}
Here's one of my finest innovations. :) I'm really proud of this little one.
public class Stringable<T>
{
private T _obj;
private Func<T, string> _convertFn;
public Stringable(T obj, Func<T, string> convertFn)
{
_obj = obj;
_convertFn = convertFn;
}
public T GetObj() { return _obj; }
public override string ToString() { return _convertFn(_obj); }
}
This generic class adds ToString() to any class (even a black-box class) and you can define its behavior inside the lambda. Imagine you have a class Person with properties FirstName and LastName. Here's how you would use it to populate Combo box.
_cboPersons.Items.Add(new Stringable<Person>(person,o=>string.Format("{0}, {1}", o.LastName, o.FirstName)));
Then, when combo box item is selected just use this to get the original object from your combo
Person person=(_cboPersons.SelectedItem as Stringable<Person>).GetObj() // Get's person object.

Categories