ListBox selector odd behavior when there are dupes - c#

I'm working on a bigger project atm, but I made this simple example to show you what happens..
using System.Collections.Generic;
using System.Windows;
namespace txt
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var obsLst = new List<Info> { new Info { name = "asd" }, new Info { name = "asd" }, new Info { name = "asd" }, new Info { name = "asd" } };
var temp = new List<Info>();
for (var i = 1; i <= 3; i++)
{
temp.Add(obsLst[0]); //I add 3 of the same item from obsLst to temp
}
lst.DataContext = temp; //lst = ListBox
}
}
public class Info
{
public string name { get; set; }
}
}
The ListBox ItemsSource is set to {Binding}..
When I start the application I get 3 txt.Info objects displayed and if I click any of them, 2 or even all of them get selected aswell. From my understanding the problem relies in the fact that the listbox selector cannot differentiate between the items and therefor doesn't know which one I selected.
Here's a picture of what it looks like..
I only clicked on the second txt.Info item.
I found a solution where someone said that I have to specify the DisplayMemberPath, but I can't really do that in the other project because I have a datatemplate for the object.
Any ideas on how I could fix this would be great..
Thx in advance.
EDIT 1:
this works but it's not nice..
using System.Collections.Generic;
using System.Windows;
namespace txt
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var obsLst = new List<Info> { new Info { name = "asd" }, new Info { name = "asd" }, new Info { name = "asd" }, new Info { name = "asd" } };
var temp = new List<Container>();
for (var i = 1; i <= 3; i++)
{
var t = new Container();
t.obj = obsLst[0];
temp.Add(t);
}
lst.DataContext = temp;
}
}
public class Info
{
public string name { get; set; }
}
public class Container
{
public Info obj { get; set; }
}
}
In this case you need to set DisplayMemberPath="obj"
Assigning an ID to the object, doesn't work..
using System;
using System.Collections.Generic;
using System.Windows;
namespace txt
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var rand = new Random();
var obsLst = new List<Info> { new Info { name = "asd" }, new Info { name = "asd" }, new Info { name = "asd" }, new Info { name = "asd" } };
var temp = new List<Info>();
for (var i = 1; i <= 3; i++)
{
obsLst[0].id = rand.Next(10000);
temp.Add(obsLst[0]);
}
lst.DataContext = temp;
}
}
public class Info
{
public string name { get; set; }
public int id { get; set; }
}
}

I had this problem too a while ago, i fixed it by adding the id # to the item so they're always different.

Related

Singleton property not updating during "OnClicked" event

I'm sure I remember this being a threading issue, but I can't find an answer. It seems like it should be simple. I have the following code:
private void Dingle_Clicked(object sender, RoutedEventArgs e)
{
dynamic doc = ScraperBrowser.Document;
string htmlText = doc.documentElement.InnerHtml;
htmlText = htmlText.Replace("\r\n", " ");
Regex targetStart = new Regex(this works just fine);
MatchCollection target = targetStart.Matches(htmlText);
string priceData = target[0].Value;
foreach (StorePriceData spData in Lists.Singleton.MedicineList[medIndex].Prices)
{
Regex rx = new Regex(spData.StoreName + #".+?(\$\d+\.\d+)");
MatchCollection matches = rx.Matches(priceData);
if (matches.Count > 0)
{
if (matches[0].Groups.Count > 0)
{
spData.MedicinePrice = matches[0].Groups[1].Value;
}
}
}
string cookie = Application.GetCookie(new Uri("https://www.goodrx.com"));
++medIndex;
ScraperBrowser.Navigate(Lists.Singleton.MedicineList[medIndex].GoodRxUrlString);
}
The problem I'm having is that the spData.MedicinePrice takes the value, but the value in the singleton "MedicineList" is not being updated. How can I make that value update?
The singleton code:
public class Lists
{
private static Lists _singleton;
public static Lists Singleton
{
get
{
if (_singleton == null) _singleton = new Lists(); return _singleton;
}
}
public List<MedicineInfo> MedicineList {
get
{
return new List<MedicineInfo>()
{
new MedicineInfo() { Name = "ZOLPIDEM TAB 10MG", Doses = "30 tablets" },
new MedicineInfo() { Name = "PANTOPRAZOLE TAB 40MG", Doses = "30 tablets" }
};
}
}
}
MedicineInfo class code:
public class MedicineInfo
{
public MedicineInfo()
{
Prices = new List<StorePriceData>()
{
new StorePriceData() { StoreName = "xxxx" },
new StorePriceData() { StoreName = "yyyy" },
new StorePriceData() { StoreName = "zzzz" },
};
}
public string Name { get; set; }
public string Doses { get; set; }
public List<StorePriceData> Prices { get; set; }
}
Thanks!
Carl
You are returning a new List<MedicineInfo> each time the getter of MedicineList is called.
Also, Lists is not really a singleton. A better implementation would look something like this:
public sealed class Lists
{
private static readonly Lists _singleton = new Lists();
private readonly List<MedicineInfo> _medicineList = new List<MedicineInfo>
{
new MedicineInfo() { Name = "ZOLPIDEM TAB 10MG", Doses = "30 tablets" },
new MedicineInfo() { Name = "PANTOPRAZOLE TAB 40MG", Doses = "30 tablets" }
};
private Lists() { }
public static Lists Singleton => _singleton;
public List<MedicineInfo> MedicineList => _medicineList;
}

Following c# code doesn't display the certificates present in local machine

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public string Name { get; set; }
public string HasPrivateKey { get; set; }
public string Location { get; set; }
public string Issuer { get; set; }
private void button1_Click(object sender, EventArgs e)
{
var stores = new Dictionary<StoreName, string>()
{
{ StoreName.My,"Personal"},
{ StoreName.Root,"Trusted roots"},
{ StoreName.TrustedPublisher,"Trusted Publishers"}
}.Select(s => new { store = new X509Store(s.Key, StoreLocation.LocalMachine), Location = s.Value }).ToArray();
foreach (var store in stores)
store.store.Open(OpenFlags.ReadOnly);
var list = stores.SelectMany(s => s.store.Certificates.Cast<X509Certificate2>().Select(mCert => new Form1
{
HasPrivateKey = mCert.HasPrivateKey ? "Yes" : "No",
Name = mCert.FriendlyName,
Location = s.Location,
Issuer = mCert.Issuer
})).ToList();
}
}
I have used windows form application in c#.
If I click the button it has to display the available certificates present in local machine onto listbox. But I don't know how to display the available certificates.. Pls give suggestions.
You create a new Form1 instance for each certificate.
You do not refer to any existing listbox
try this:
public partial class Form1 : Form
{
//declare new listbox
ListBox lbCerts;
public Form1()
{
InitializeComponent();
//add a listbox to the form
lbCerts = new ListBox();
lbCerts.DisplayMember = "Name";
this.Controls.Add(lbCerts);
}
//class represent certificate
class myCer
{
public string Name { get; set; }
public string HasPrivateKey { get; set; }
public string Location { get; set; }
public string Issuer { get; set; }
}
private void button1_Click(object sender, EventArgs e)
{
var stores = new Dictionary<StoreName, string>()
{
{ StoreName.My,"Personal"},
{ StoreName.Root,"Trusted roots"},
{ StoreName.TrustedPublisher,"Trusted Publishers"}
}.Select(s => new { store = new X509Store(s.Key, StoreLocation.LocalMachine), Location = s.Value }).ToArray();
foreach (var store in stores)
store.store.Open(OpenFlags.ReadOnly);
//create list of myCer
var list = stores.SelectMany(s => s.store.Certificates.Cast<X509Certificate2>().Select(mCert => new myCer
{
HasPrivateKey = mCert.HasPrivateKey ? "Yes" : "No",
Name = mCert.FriendlyName,
Location = s.Location,
Issuer = mCert.Issuer
})).ToList();
//populate listbox
lbCerts.DataSource = list;
}
}

How do i properly initialize a variable with a custom type

This is the code in C#:
public bool IsNation(string country)
{
for (int i = 0; i < Nations.Count; i++)
{
if (Nations[i].Name == country)
{
return true;
}
else { return false; }
}return true;
}
In C# you must initialize variables. But what if you made one of your own like this below?
public class WorldMarket
{
public WorldMarket()
{
Nations = new List<NationBuilder>();
}
internal List<NationBuilder> Nations { get; set; }
public void AddToWorldMarket(NationBuilder nation)
{
Nations.Add(nation);
}
The main idea is that from this structure:
- wm
- Nations
- [0]
- Name "USA"
- stockpile
- [0]
- Name "Coal"
- Quantity "quantity"
- Value "value"
- [1] //Same as above
Find the country Name "USA" or whatever name inside this structure with a function that by only inserting a string with a name it outputs {1 or 0}
or True or False (if type == bool).
My attempt is the first code presented in this question. It tries to "travel" the structure and find the Name Tag you input as country using this call.
IsNation(string country); where country can be whatever string input.
Question
If C# wants me to declare every variable with an initial value, how do i do it with this custom or whatever custom type i may do?
Initialize the variable in the constructor public WorkdMarket(). See code below :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
WorldMarket wm = new WorldMarket();
}
}
public class WorldMarket
{
internal List<NationBuilder> Nations { get; set; }
public WorldMarket()
{
Nations = new List<NationBuilder>() {
new NationBuilder() {
name = "USA",
stockPiles = new List<StockPile>() {
new StockPile() { name = "Coal", quantity = 2, value = "value"},
new StockPile() { name = "Coal", quantity = 2, value = "value"}
}
}
};
}
public void AddToWorldMarket(NationBuilder nation)
{
Nations.Add(nation);
}
}
public class NationBuilder
{
public string name { get; set; }
public List<StockPile> stockPiles { get; set; }
}
public class StockPile
{
public string name { get; set; }
public int quantity { get; set; }
public string value { get; set; }
}
}
The line you requested would be:
WorldMarket con = new WorldMarket();
However, this would initialize as a new WorldMarket object, which has no pre-populated values yet. If the nations are meant to be static, you could initialize all the nations within the WorldMarket class
public class WorldMarket
{
public WorldMarket()
{
Nations = new List<NationBuilder>() {
new NationBuilder() {
name = "USA",
...
},
new NationBuilder() {
name = "AUS",
...
}
}
}
}
Or alternatively if you could have your isNation method within WorldMarket, that might work better such that.
public class WorldMarket()
{
// various class constructor methods
public int IsNation(string country)
{
// you could access Nations directly here
for (int i = 0; i < Nations.Count; i++)
{
if (Nations[i].Name == country)
{
return 1;
}
// else { return 0; } -- this would exit the loop unnecessarily
}
return 0;
}
}
and the usage in your main program would be something like
program static void Main(string[] args)
{
WorldMarket con = new WorldMarket();
con.AddToWorldMarket(new NationBuilder() {
name = "USA",
...
}
Console.WriteLine(con.IsNation("USA"));
}
}

Dropdown has a SelectedValue which is invalid because it does not exist in the list of items, even though I cleared the selected items (C#)

I'm getting this error on DataBind(), and I don't know why since there shouldn't be anything selected.
DdState.Items.Clear();
DdState.DataSource = UsStates;
DdState.DataTextField = "Title";
DdState.DataValueField = "Title";
DdState.Items.Insert(0, String.Empty);
if (DdState.SelectedItem != null)
{
DdState.SelectedItem.Selected = false;
}
DdState.DataBind();
private IEnumerable<IStateItem> UsStates
{
get
{
var statesFolder = _sitecoreService.GetItem<ISitecoreItem>(ItemReference.BcsUs_ProductData_States.Guid);
if (statesFolder == null)
return new List<IStateItem>();
List<IStateItem> usStates = _sitecoreService.QueryChildren<IStateItem>(statesFolder).OrderBy(s => s.Title).ToList();
return usStates;
}
}
I tried putting in DdState.SelectedIndex = 0 before the DataBind(), but then I got an error that the selected index did not exist. What's going on?
If the DataSource is a list its much easier to implement. So just "convert" the UsStates IEnumerable to a List an then add it to the data source.
DdState.DataSource = UsStates.ToList();
Then choose the property of a list item as binding.
OR
public Form1()
{
InitializeComponent();
DdState.Items.Clear();
DdState.DataSource = UsStates;
DdState.DisplayMember = "Statename";
DdState.SelectedIndex = 0;
}
private List<IStateItem> UsStates
{
get
{
List<IStateItem> usStates = new List<IStateItem>();
usStates.Add(new IStateItem("California","status1"));
usStates.Add(new IStateItem("Ohio", "status3"));
return usStates;
}
}
private class IStateItem
{
public IStateItem(string statename, string stateStatus)
{
Statename = statename;
StateStatus = stateStatus;
}
public string Statename { get; set; }
public string StateStatus { get; set; }
}
Could there be something wrong with your IStateItem class?
I copy/pasted your code in a new asp.net application, made my own IStateItem class and it works.
using System;
using System.Collections.Generic;
namespace TestIt
{
public partial class Form1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
FillTheList();
}
private void FillTheList()
{
ddl_TheList.Items.Clear();
ddl_TheList.DataSource = UsStates;
ddl_TheList.DataTextField = "statename";
ddl_TheList.DataValueField = "stateStatus";
//ddl_TheList.Items.Insert(0, String.Empty);
ddl_TheList.DataBind();
ddl_TheList.SelectedIndex = 0;
}
private IEnumerable<IStateItem> UsStates
{
get
{
List<IStateItem> usStates = new List<IStateItem>();
for (int i = 0; i < 10; i++)
{
usStates.Add(new IStateItem { statename = "state #" + i, stateStatus = "cool state bro" });
}
return usStates;
}
}
}
public class IStateItem
{
public string statename { get; set; }
public string stateStatus { get; set; }
}
}

DevExpress PropertyGridControl CustomEditor assignment

Want to assign CustomEditor to PropertyGridControl. If I try using default way it does not work, however I am trying alternative which is not suitable for my case.
Class and Custom editor which is needs to be assigned to PropertyGridControl:
public class Foo
{
public Foo()
{
}
public Language LanguageOfFoo { get; set; }
}
public class Language
{
public Language()
{
}
public int ID { get; set; }
public string Name { get; set; }
}
public class RepositoryItemForLanguage : RepositoryItemLookUpEdit
{
public RepositoryItemForLanguage()
{
this.Columns.AddRange(new DevExpress.XtraEditors.Controls.LookUpColumnInfo[] {
new DevExpress.XtraEditors.Controls.LookUpColumnInfo("Name", "Name")}
);
this.DisplayMember = "Name";
List<Language> tmpList = new List<Language>();
tmpList.Add(new Language { ID = 1, Name = "AZE" });
tmpList.Add(new Language { ID = 2, Name = "ENG" });
tmpList.Add(new Language { ID = 1, Name = "RUS" });
this.DataSource = tmpList;
}
}
Default way:
private void button1_Click(object sender, EventArgs e)
{
propertyGridControl1.Rows.Clear();
propertyGridControl1.DefaultEditors.Clear();
propertyGridControl1.RepositoryItems.Clear();
propertyGridControl1.SelectedObject = null;
Foo f1 = new Foo();
f1.LanguageOfFoo = new Language();
RepositoryItemForLanguage repItem = new RepositoryItemForLanguage();
propertyGridControl1.RepositoryItems.Add(repItem);
propertyGridControl1.DefaultEditors.Add(typeof(Language), repItem);
propertyGridControl1.DefaultEditors.AddRange(new DevExpress.XtraVerticalGrid.Rows.DefaultEditor[] {
new DevExpress.XtraVerticalGrid.Rows.DefaultEditor(typeof(Language), repItem)});
propertyGridControl1.RepositoryItems.AddRange(new RepositoryItem[] { repItem});
propertyGridControl1.SelectedObject = f1;
}
Alternative method:
private void button1_Click(object sender, EventArgs e)
{
propertyGridControl1.Rows.Clear();
propertyGridControl1.DefaultEditors.Clear();
propertyGridControl1.RepositoryItems.Clear();
propertyGridControl1.SelectedObject = null;
Foo f1 = new Foo();
f1.LanguageOfFoo = new Language();
RepositoryItemForLanguage repItem = new RepositoryItemForLanguage();
propertyGridControl1.RepositoryItems.Add(repItem);
propertyGridControl1.SelectedObject = f1;
propertyGridControl1.GetRowByFieldName("LanguageOfFoo").Properties.RowEdit = repItem;
}
As you see it is possible only with "GetRowByFieldName" methods and specifying exact property name.
Appreciate for your help.

Categories