I have a list of objects:
List<NFutures> futureContracts = new List<NFutures>();
What I would like to do is the following:
Every time I change the value of a object property in the list:
foreach (NFuture fut in futureContracts)
{
if (fut.Name == aName)
{
fut.PriceLast = i.StatusLine.Last;
}
}
The chart will update.
The class definition is...
public class NFuture : NInstrument
{
public double Dtm { get; set; }
public double PriceLast { get; set; }
etc ...
How can this be done in an easy way?
futureContracts.FirstOrDefault(x=>x.Name ==aName).PriceLast = "your Value";
Related
I have three classes:
public class M2ArticleMain
{
public int Id { get; set; }
public List<M2ArticleAttributeWeb> Attribut_Web { get; set; }
}
public class M2ArticleAttributeWeb
{
public int Web_Id { get; set; }
public M2ArticleTmpMainSkus Variants { get; set; }
}
public class M2ArticleTmpMainSkus
{
public DateTime TimeAdded { get; set; }
public List<string> Skus { get; set; }
}
And I have two Lists in my code like this:
List<M2ArticleMain> data = new List<M2ArticleMain>();
List<M2ArticleAttributeWeb> attb = new List<M2ArticleAttributeWeb>();
In some part of my code firstly I (from foreach loop) add data to attb list where I add only only some data (because I don't have all data at this point), like this:
...
attb.Add(new M2ArticleAttributeWeb
{
Web_id = item.Id, //(item is from foreach loop)
Variants = null //this is **importat**, I left null for later to add it
});
Next, after I fill attb, I add all this to data list:
...
data.Add(new M2ArticleMain
{
Id = item.Id_Pk, //this is also from foreach loop,
Attribut_Web = attb //now in this part I have only data for Web_id and not Variants
}
Now my question is How to Add items later to data list to object Variants?
Something like this:
data.AddRange( "how to point to Variants" = some data);
The M2ArticleAttributeWeb type holding your Variants property is the member of a collection. That is, there are potentially many of them. You can reference an individual Variants property like this:
data[0].Attribut_Web[0].Variants
But you need to know which items you want to add map to which data and Attribut_Web indexes/objects in order to assign them properly. That probably means another loop, or even a nested loop. That is, you can see all of your Variants properties in a loop like this:
foreach(var main in data)
{
foreach(var attrw in main)
{
var v = attrw.Variants;
// do something with v
Console.WriteLine(v);
// **OR**
attrw.Variants = // assign some object
}
}
It's also much better practice to create your collection properties with the object, and then give them private set attributes:
public class M2ArticleMain
{
public int Id { get; set; }
public List<M2ArticleAttributeWeb> Attribut_Web { get; private set; } = new List<M2ArticleAttributeWeb>();
}
public class M2ArticleAttributeWeb
{
public int Web_Id { get; set; }
public M2ArticleTmpMainSkus Variants { get; set; }
}
public class M2ArticleTmpMainSkus
{
public DateTime TimeAdded { get; set; }
public List<string> Skus { get; private set; } = new List<string>();
}
Now instead of assigning Attribut_Web = attb, you would need to .Add() to the existing List.
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 1 year ago.
I have a class with this:
public class myDataType
{
public class GetInvoice
{
public string InvoiceID { get; set; }
public string InvoiceNumber { get; set; }
public decimal InvoiceAmount { get; set; }
public List<InvoiceRow> Rows { get; set; }
}
public class InvoiceRow
{
public decimal RowQty { get; set; }
public string RowCode { get; set; }
public string RowDescription { get; set; }
}
}
And when I want to add data has th
using static test.myDataType;
...
private void LoadData()
{
GetInvoice Invoice = new GetInvoice();
Invoice.InvoiceID = "0a8625e5-62f6-4ad7-a8bf-ab04b1158392";
Invoice.InvoiceNumber = "Inv-001";
Invoice.InvoiceAmount = 100;
Invoice.Rows.Add(new InvoiceRow { RowQty= 1, RowCode = "C100", RowDescription = "Item C100"});
}
When try to add the row:
Invoice.Rows.Add(new InvoiceRow { RowQty= 1, RowCode = "C100",
RowDescription = "Item C100"});
Show me this error "System.NullReferenceException: 'Object reference not set to an instance of an object'"
I think i have a sintax o wrong way to do it
Can someone help?
Thanks in advance
It's not a syntax error, you just haven't initialised the list.
With
public List<InvoiceRow> Rows { get; private set; }
you've declared a place to hold the list, but haven't created the list itself.
(If an analogy helps, imagine you've drawn a line on the wall of your house where you're going to put up a bookshelf, but you haven't actually screwed the shelf to the wall yet - that's the situation your code is in).
If you want the list to always be available you can either initialise it automatically through the property declaration, or in the constructor of the class. Alternatively of course you could leave the calling code to initialise it.
This version just makes it part of the property declaration:
public List<InvoiceRow> Rows { get; private set; } = new List<InvoiceRow>();
You need first to initialize list Rows before you add element to it.
For example in GetInvoice class you can add:
public List<InvoiceRow> Rows { get; set; } = new List<InvoiceRow>();
List is reference type in C# so it needs to be initialized before being used.
If you want to do that in LoadData() method you can do in this way:
private void LoadData()
{
GetInvoice Invoice = new GetInvoice();
Invoice.InvoiceID = "0a8625e5-62f6-4ad7-a8bf-ab04b1158392";
Invoice.InvoiceNumber = "Inv-001";
Invoice.InvoiceAmount = 100;
Invoice.Rows = new List<InvoiceRow>();
Invoice.Rows.Add(new InvoiceRow { RowQty = 1, RowCode = "C100", RowDescription = "Item C100" });
}
Sorry if this is a simple question but if I want to have a list inside a model, and later access and set the values of the list?
Say my main model looks like this:
public class StartPageModel : IPageViewModel<StartPage>
{
public IList<ListContent> ListContent { get; set; }
public StartPage CurrentPage { get; set; }
}
public class ListContent
{
public IList<ListElement> ArticleListContent { get; set; }
public IList<ListElement> InsightListContent { get; set; }
}
How can I set the ArticleListContent list to a value by referencing the parent model?
public ActionResult Index(StartPage currentPage)
{
var model = new StartPageModel(currentPage);
model.ListContent.ArticleListContent = GetListContent(currentPage.ArticleCollection);
}
However this returns the error:
IList does not contain a definition for 'ArticleListContent'
I'm not sure you require a collection of ListContent in your StartPageModel, correct me if I'm wrong.
Change
public IList<ListContent> ListContent { get; set; }
to
public ListContent ListContent { get; set; }
And provided ListContent is initialized, your assignment will work.
It's because it's referencing the List of ListContent, not an individual item in that list. Here's some examples:
var model = new StartPageModel(currentPage);
model.ListContent[0].ArticleListContent = GetListContent(currentPage.ArticleCollection); // Access first in list
model.ListContent[1].ArticleListContent = GetListContent(currentPage.ArticleCollection); // Access secondin list
model.ListContent.First().ArticleListContent = GetListContent(currentPage.ArticleCollection); // Access first in list using Linq
I was trying to populate a DevExpress gridview with some datas.
Let's say we have two classes :
public class ObjectA
{
public string Name { get; set; }
public List<ObjectB> Details1 { get; set; }
public List<ObjectB> Details2 { get; set; }
}
public class ObjectB
{
public string Name { get; set; }
public string Description { get; set; }
}
And a form created like that :
private List<ObjectA> datas;
public Form1()
{
InitializeComponent();
// Fill data
datas = ...
// Set datasource
this.gridControl1.DataSource = datas;
this.gridView1.BestFitColumns();
this.SetRelation();
}
private void SetRelation()
{
GridView customPatternView = new GridView(gridControl1);
customPatternView.Columns.AddField("Name").VisibleIndex = 0;
customPatternView.Columns.AddField("Description").VisibleIndex = 1;
this.gridControl1.LevelTree.Nodes.Add("CustomRelation", customPatternView);
}
This code is working well but I'm obly able to display Details1 in the details view.
How can I do to display only Details2 ?
Thanks
You need one GridView for each detail view.
gridControl1.LevelTree.Nodes.Add("Details1", customPatternView);
gridControl1.LevelTree.Nodes.Add("Details2", customPatternView);
You can use GridControl.ShowOnlyPredefinedDetails property. If you set this property to true then the GridControl displays only the relationships that exist in the LevelTree. Also, use the name of your child list property as relation name in GridControl.LevelTree.Nodes.Add method.
Here is example:
private void SetRelation()
{
var customPatternView = new GridView(gridControl1);
customPatternView.Columns.AddField("Name").VisibleIndex = 0;
customPatternView.Columns.AddField("Description").VisibleIndex = 1;
this.gridControl1.LevelTree.Nodes.Add("Details2", customPatternView);
this.gridControl1.ShowOnlyPredefinedDetails = true;
}
I'm having an instance where I have an object that looks similar to this:
public class answerObject
{
public string Q1 { get; set; }
public string Q2 { get; set; }
public string Q3 { get; set; }
public string Q4 { get; set; }
public string Q5 { get; set; }
...
public string Q80 { get; set; }
}
The questions themselves look like this:
public class questionObject
{
public string DataMember { get; set; }
...
}
The DataMember string carries a string version of the answer object element. So, if I have question 1 have a datamember of "Q1" then I want it to fill in answerObject.Q1 and so on. Right now I have a lengthy switch statement to solve this, but there has to be a more efficient way to do this.
switch(DataMember) {
case "Q1":
answerObject.Q1 = answerValue;
break;
case "Q2":
answerObject.Q2 = answerValue;
break;
....
};
I've researched for a few hours and didn't come up with anything. Any help is much appreciated.
You can use Reflection for that but I would keep using the switch/case:
var property = typeof(answerObject).GetProperty(DataMember);
if(property != null) property.SetValue(yourInstance, answerValue);
After your edit using Reflection makes more sense.Anyway you can also put this code into an extension method:
public static void SetAnswer(this answerObject instance, string question, string value)
{
var property = typeof(answerObject).GetProperty(question);
if (property != null) property.SetValue(instance, value);
else { // throw exception or display a message }
}
A possible solution is to use a Dictionary object - make your Questions a dictionary and set the string Q1, Q2, etc. as key (your DataMember would later be filled with one of the keys). Then to assign the question just use the already set DataMember and the item property of the Dictionary object. The code could look like this:
public class QuestionObject
{
public string DataMember { get; set; }
public String Answer { get; set; }
}
public class AnswerObject
{
public Dictionary<String, String> Questions { get; set; }
public AnswerObject()
{
Questions = new Dictionary<String, String>();
// init the question keys
Enumerable.Range(1, 80).ToList().ForEach(index =>
{
Questions.Add(String.Format("Q{0}", index), String.Empty);
});
}
}
And the usage looks like this:
var question = new QuestionObject();
var answer = new AnswerObject();
question.DataMember = #"Q75";
// set the question = the same as the switch/case
answer.Questions[question.DataMember] = #"and the answer is ...";