Winforms combobox displaying class names instead of actual object name - c#

I have this class that contains a static list
public class TypeList
{
public string Name;
public string NameTag;
public TypeList(string Name, string NameTag)
{
this.Name = Name;
this.NameTag = NameTag;
}
public static List<TypeList> DataType = new List<TypeList>() {
new TypeList("DataType","-1"),
new TypeList("OpOne","1"),
new TypeList("OpTwo","2"),
};
}
I then put the static list called DataType into a combobox:
public void RefreshList()
{
List<TypeList> data = new List<TypeList>();
data = TypeList.DataType;
typeCB.DataSource = data;
typeCB.DisplayMember = "Name";
typeCB.ValueMember = "NameTag";
typeCB.SelectedValue = -1;
typeCB.SelectedText = "Select DataType";
}
However, when I run it, all I get are the classnames in my combobox. Is something wrong with my code? I tried to do
data.Select(x=>x.Name).ToList()
But that just gives me the name portion.

I might be wrong, but based on the Documentation and Example it might be that this Feature only works with public property getters, not public fields:
Gets or sets the property to display for this ListControl.
public class USState
{
private string myShortName;
private string myLongName;
public USState(string strLongName, string strShortName)
{
this.myShortName = strShortName;
this.myLongName = strLongName;
}
public string ShortName
{
get
{
return myShortName;
}
}
public string LongName
{
get
{
return myLongName;
}
}
}
Of course I would also advise against making the list a part of the Type class. A simple Programm scope static would be better. If that is the case and as autoproties have have become a thing by now, this should be enough of a fix:
public class Type
{
public string Name { private set; get } ;
public string NameTag {private set; get };
public TypeList(string Name, string NameTag)
{
this.Name = Name;
this.NameTag = NameTag;
}
}
//use in the class of main, the form or some similar central point
static List<Type> TypeList = new List<Type>();

Related

Simplify passing nameof(someObject) and someObject as parameters to a method

I have a method where I'm currently passing in both someObject and nameof(someObject) since I'm using this method many times I'm wanting to simplify my code by finding a way to only pass in the object once but if I do the nameof() inside the method I'm obviously not going to get the name I want.
What I have currently is something like this:
public record ResourceObject
{
public string Name { get; init; }
public byte[] File { get; init; }
public string Content { get; init; }
public ResourceObject(string name, byte[] file)
{
Name = name;
File = file;
Content = Encoding.Default.GetString(file);
}
}
Where the use looks like this:
var test = new ResourceObject(nameof(Properties.Resources.SomeResource), Properties.Resources.SomeResource)
Ideally, I'd like to get the use to look like this(I don't think this is possible):
var test = new ResourceObject(Properties.Resources.SomeResource)
I did find a post that shows getting the name like this but then I can't get the object itself:
public record ResourceObject
{
public string Name { get; init; }
public byte[] File { get; init; }
public string Content { get; init; }
private ResourceObject(string name, byte[] file)
{
Name = name;
File = file;
Content = Encoding.Default.GetString(file);
}
public static ResourceObject New<T>(Expression<Func<T>> property)
{
var name = (property.Body as MemberExpression).Member.Name;
var file = ???; //I can't figure out how to get the object itself here
return new(name, file);
}
}
The use for that looks like this (which would be great improvement over what I if I could get it to work):
var test = ResourceObject.New(() => Resources.TradeEngineSettings_Base);
This is what ultimately worked for me.
public record ResourceObject<T>
{
public string Name { get; }
public T Object { get; }
public string Content { get; }
public ResourceObject(T #object, [CallerArgumentExpression(nameof(#object))] string name = null)
{
Name = name.Split('.', StringSplitOptions.RemoveEmptyEntries)[^1];
Object = #object;
if (#object?.GetType() == typeof(byte[]))
{
Content = Encoding.Default.GetString(#object as byte[] ?? Array.Empty<byte>());
}
}
}
To keep Name more similar to a nameof() behavior, name is split on '.' and only takes the last item in the array.

List to JSON with JsonSerializer.Serializer returns null

I have a class named clsTest which is defined as:
public class clsTest
{
public string Name;
public string Family;
public int Age;
}
I have another class named clsMain which is Serializing three instances of clsTest class to JSON as:
public class clsMain
{
public string mtdMain()
{
clsTest ct1_a = new clsTest();
clsTest ct1_b = new clsTest();
clsTest ct1_c = new clsTest();
ct1_a.Name = "Satoshi";
ct1_a.Family = "Nakamato";
ct1_b.Name = "Charles";
ct1_b.Family = "Hoskinson";
ct1_b.Age = 33;
ct1_c.Name = "AmirAli";
ct1_c.Family = "Sam";
ct1_c.Age = 25;
List<clsTest> lst = new List<clsTest>();
lst.Add(ct1_a);
lst.Add(ct1_b);
lst.Add(ct1_c);
JsonSerializerOptions option = new JsonSerializerOptions();
option.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
option.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
return JsonSerializer.Serialize(lst, option);
}
}
When I debug the project my list is full as shown in the screenshot:
But at the end return JsonSerializer.Serialize(lst, option); serialize as below:
I couldn't find the problem, any suggestion will be appreciated.
Thanks.
Use properties instead of fields, like so:
public class Test
{
public string Name { get; set; }
public string Family { get; set; }
public int Age { get; set; }
}

JavaScriptSerializer does not serialize a second level

I am trying to use JavaScriptSerializer and I have got good results when I want to serialize a list of objects of a class like
public class employee
{
public string id; //unique id of the employee
public string displayName;
public int displayFlag;
public employee(string i, string dN, int dF)
{
id = i;
displayName = dN;
displayFlag = dF;
}
}
public class data2
{
public List<employee> detail;
}
When I do the following
var json = new JavaScriptSerializer();
string jsonData = json.Serialize(data2);
(and data2 is an object of class data2)
However when I try to do the same for something a little more complicated such as
public class Ccanister
{
string identifier;
public Ccanister(string c)
{
identifier = c;
}
}
public class medicine
{
public string id; //unique id
public string displayName;
//and here an array of canisters
public List<Ccanister> canister;
}
public class dataMedicine
{
public List<medicine> detail; //Change this
}
and I do this
string jsonMedi = json.Serialize(dataM);
I got wrong results.
dataM has correct results (I debugged it) but when jsonMedi gets its results, the canister list 'canister' is always empty. (It was not empty in dataM)
I wonder what I am doing wrong here

Static Nested Type

So i have nested type classes that go something like this:
namespace MyNamespace
{
public class User
{
private int id = 0;
private string userId = "";
private string userPassword = "";
public int Id
{
get { return id; }
set { id = value; }
}
public string UserId
{
get { return userId; }
set { userId = value; }
}
public string UserPassword
{
get { return userPassword; }
set { userPassword = value; }
}
public User()
{
id = 0;
userId = "";
userPassword = "";
}
public static class SignonInfo
{
private static string sesstoken = "";
private static DateTime sessstart = new DateTime();
public static string SessToken
{
get { return sesstoken; }
set { sesstoken = value; }
}
public static DateTime SessStart
{
get { return sessstart; }
set { sessstart = value; }
}
}
}
}
My end goal here was to be able to access the nested static class like this:
User user = new User();
string token = user.SignonInfo.SessToken;
I'm trying to avoid instantiating the class like this:
User.SignonInfo user = new User.SignonInfo()
I need to be able to access properties of both User and SignonInfo classes.
Could someone help me to get on track or slap me about and tell me i'm doing it all wrong?
TIA
The problem is that it's a static class, so an "instance" doesn't have access to it. This is a good thing, as it prevents global state from masquerading as a well-encapsulated object.
I'd suggest making the nested class non-static, and having theUser class create an instance as needed by the caller (maybe add a public SignonInfo GetSignonInfo() method.)
You are trying to access your nested class as if it were a member of the instance of the outer class.
Change
string token = user.SignonInfo.SessToken;
to
User.SignonInfo.SessToken;
Note, that you do not get an instance of the static nested type per outer instance, there is only one for the entire outer class.

Constructors GetInfo

I am new to C# and am working on classes and understanding them. My problem is I am not understanding how to create a Get to retrieve the private variable _yourname and Set to set the private variable _yourname.
namespace WindowsFormsApplication1
{
class InputClass
{
private string _yourName;
public string _banner;
public virtual void GetInfo();
public InputClass(String _banner)
{
_banner = "Enter your name";
}
}
}
Maybe I am using the wrong function to GetInfo. But I am also wondering when I have the GetInfo if in the () I should write _yourname in it.
In C# there are properties, which have the function of public getter and setter methods in other languages:
class InputClass
{
private string _yourName;
public string _banner;
public InputClass(String _banner)
{
this._banner = _banner;
}
public string YourName
{
get { return _yourName; }
set { _yourName = value; }
}
}
But you can use auto properties, if you want:
class InputClass
{
public InputClass(String _banner)
{
Banner = _banner;
}
public string YourName
{
get; set;
}
public string Banner
{
get; set;
}
}
It sounds like you are trying to provide access to the _yourName field. If so then just use a property
class InputClass {
public string YourName {
get { return _yourName; }
set { _yourName = value; }
}
...
}
Now consumers of InputClass can access it as if it were a read only field.
InputClass ic = ...;
string yourName = ic.YourName;
ic.YourName = "hello";
Note: C# provides a special syntax for simple properties like this which are just meant to be wrappers over private fields. It's named auto-implemented properties
class InputClass {
public string YourName { get; set; }
}
You can override getters and settings using the get and set keywords. For example:
class InputClass
{
private string _yourName;
private string _banner;
public YourName
{
get { return _yourName; }
set { _yourName = value; }
}
public Banner
{
get { return _banner; }
set { _banner = value; }
}
public InputClass(String banner)
{
_banner = banner;
}
}
1.) Use properties instead of members, you get a free accessor (get) and mutator (set).
public string YourName { get; set; }
public string Banner { get; set; }
2.) You can take advantage of the default constructor, and declare it on the fly.
//the old way:
InputClass myClass = new InputClass();
myClass.YourName = "Bob";
myClass.Banner = "Test Banner";
//on the fly:
InputClass myClass = new InputClass()
{
YourName = "Bob",
Banner = "Test Banner"
}

Categories