C# Reflection. Set TableAdapter ConnectionString - c#

I've been trying to create a new base class for a Windows Forms form. I want to have this base class go through all the tableadapters it has on it and update their connection strings without anyone adding any code to the form. They just put the tableadapters on the form and don't worry about the connection string settings as it's all handled in the base class.
The problem is my reflection code can find the property fine, but it can't set it. How can I fix it?
Below is the code:
public class cFormWS : Form
{
public string ConnectionStringToUse { get; set; }
public cFormWS()
{
Load += cFormWS_Load;
}
void cFormWS_Load(object sender, EventArgs e)
{
InitiliseTableAdapters();
}
private void InitiliseTableAdapters()
{
var ListOfComponents = EnumerateComponents();
foreach (var ItemComp in ListOfComponents)
{
if (ItemComp.ToString().ToLower().EndsWith("tableadapter"))
{
var ItemCompProps = ItemComp.GetType().GetRuntimeProperties();
var TASQLConnection =
ItemCompProps.FirstOrDefault(
w => w.PropertyType == typeof(System.Data.SqlClient.SqlConnection));
if (TASQLConnection != null)
{
var property = typeof(System.Data.SqlClient.SqlConnection).GetProperty("ConnectionString");
// How do I set the value?
string value = "some new connection string";
var ConvertedProperty = Convert.ChangeType(value, property.PropertyType);
// I tried seting a value. It is not working:
// "object does not match target type"
property.SetValue(TASQLConnection, ConvertedProperty, null);
//// I tried using a method. It is not working:
//// "object does not match target type"
//var m = property.SetMethod;
//ParameterInfo[] parameters = m.GetParameters();
//m.Invoke(m, parameters); // m.Invoke(this, parameters); // m.Invoke(ItemComp, parameters);
}
}
}
}
private IEnumerable<Component> EnumerateComponents()
{
return from field in GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
where typeof(Component).IsAssignableFrom(field.FieldType)
let component = (Component)field.GetValue(this)
where component != null
select component;
}

When you do SetValue, you need to pass in the object that you wish to set the property on.
In your first example code, you passed in ItemComp: This is incorrect, since the ConnectionString is a property of the SqlConnection which is a property of ItemComp
In your edited question (and my original answer) you pass in the TASqlConnection. However, this is not the object, but a PropertyInfobased of the object
The correct way is to get the value from the ItemComp object and pass that in:
property.SetValue(TASQLConnection.GetValue(ItemComp), ConvertedProperty, null);
ORIGINAL (INCORRECT) ANSWER:
You're trying to set a ConnectionString property of ItemComp. The ConnectionString is not a property of the TableAdapter, but of the SqlConnection (which is a property of the TableAdapter).
The correct way of setting the property would be this:
property.SetValue(TASQLConnection, ConvertedProperty, null);

Related

Get 'Non-persisted field' value from PXSmartPanel

I am using a PXSmartPanel to display a dialog allowing a user to enter a string. I would like to use a 'Non-persisted field', but that means (I think) that I would have to get the field value by calling the field on the Panel and extracting its value.
The text field's ID is cstFieldSSN and the non-persisted field's ID is UsrSSN
My method looks like this:
(I'm calling the dialog upon clicking a menu item)
// Initialize 'myPanel'
public PXFilter<PX.Objects.CR.Contact> myPanel;
// Make the 'Letters' menu available to 'Automation Steps'
public PXAction<PX.Objects.CR.Contact> letters;
[PXUIField(DisplayName = "Letters", MapEnableRights = PXCacheRights.Select)]
[PXButton(SpecialType = PXSpecialButtonType.Report)]
protected virtual IEnumerable Letters(PXAdapter adapter, string reportID)
{
if (myPanel.AskExt(true) != WebDialogResult.OK) return;
PXReportRequiredException ex = null;
Contact contact = Base.Caches[typeof(Contact)].Current as Contact;
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["ContactID"] = contact.ContactID.ToString();
/** Here's the issue **/
parameters["SSN"] = myPanel.Current.UsrSSN;
throw new PXReportRequiredException(parameters, reportID, "");
if (ex != null) throw ex;
return adapter.Get();
}
I'm getting
'PX.Objects.CR.Contact' does not contain a definition for 'UsrSSN' and no extension method 'UsrSSN' accepting a first argument of type 'PX.Objects.CR.Contact' could be found (are you missing a using directive or an assembly reference?)
Could someone help me out or point me to a resource?
Thanks to #Brendan, my final code looks like this:
// Initialize 'myPanel'
public PXFilter<PX.Objects.CR.Contact> myPanel;
// Make the 'Letters' menu available to 'Automation Steps'
public PXAction<PX.Objects.CR.Contact> letters;
[PXUIField(DisplayName = "Letters", MapEnableRights = PXCacheRights.Select)]
[PXButton(SpecialType = PXSpecialButtonType.Report)]
protected virtual IEnumerable Letters(PXAdapter adapter, string reportID)
{
// Launch the PXSmartPanel dialog and test result
if (myPanel.AskExt(true) == WebDialogResult.OK)
{
PXReportRequiredException ex = null;
Contact contact = Base.Caches[typeof(Contact)].Current as Contact;
Dictionary<string, string> parameters = new Dictionary<string, string>();
//*** Get the extended class
var myExt = myPanel.Current.GetExtension<ContactExt>();
parameters["ContactID"] = contact.ContactID.ToString();
//*** Get the extended class's custom field value
parameters["SSN"] = myExt.UsrSSN;
throw new PXReportRequiredException(parameters, reportID, "");
if (ex != null) throw ex;
}
return adapter.Get();
}
But I also had to set the CommitChanges property on the text field to True so that the value would be pushed back to the cached Contact, allowing me to use it.

C# Referring to the current form through a static method

I'm working on a method that is static, and returns a value off a WinForm, it spawns the new form on a button click, and upon hitting the submit or cancel buttons it throws back its value.
The issue is, I cant refer to a combobox control on my form to populate it with the results of my sqlreader.
I have read suggestions that I use a wrapper that looks akin to
public ComboBox comboHolder { get return this.foo }
however I can't seem to refer to it either. Any suggestions to remedy this ?
Full code
public ComboBox comboboxWrapper
{
get { return this.comboUsernames; }
}
public static string SelectProfile()
{
Form selectProfile = new Select_Profile();
selectProfile.ShowDialog();
SqlConnection connection = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Users.mdf;Integrated Security=True;Connect Timeout=30");
connection.Open();
SqlCommand command = new SqlCommand("SelectAllUsers", connection);
SqlDataReader usersReader = command.ExecuteReader();
List<string> accountNames = new List<string>();
while (usersReader.Read())
{
accountNames.Add((string)usersReader["Username"]);
}
//populate the combo box
foreach (string s in accountNames)
{
//I'd like to call comboboxWrapper here.
}
//set the combo box to have a default item
// combo.SelectedIndex = 0;
}
Also, this is a work in progress, I realize I should have some try, catch and a finally statement, other than that i'm open to any suggestions for code improvement.
Thanks!
I would suggest just not making the method static. But if you really need to for some reason, you could pass a reference to the form into your static method, e.g.:
SelectProfile(Form myForm)
Then you would be able to use it inside the method like this:
foreach (string s in accountNames)
{
// e.g myForm.comboboxWrapper
}
your static method need object of class for that you have to pass object of class where comboboxwrapper defined
public static string SelectProfile(ClassobjectofCoboboxWrapper obj)
{
obj.comboboxWrapper;
}
Call to this method from outside
SelectProfile(new ClassobjectofCoboboxWrapper())
Note:
As static method are not related to instace of object its related to class. So to refer element in static method which are not static you either need to create object of refering class or you need to pass object of class your want to refer.
This is your form instance:
Form selectProfile = new Select_Profile();
So you'd call comboboxWrapper on that instance:
selectProfile.comboboxWrapper
Though first you'll need to change its type, since Form doesn't have a member called comboboxWrapper. Declare it like this instead:
Select_Profile selectProfile = new Select_Profile();
or simply:
var selectProfile = new Select_Profile();
Even though the comboboxWrapper member is defined outside the static method, it's inside the form instance. A static member has no default notion of a particular instance and needs to be provided with one. Or, in this case, internally creates one.
First, decompose your solution: just don't cram database and UI into single method. Next think over what your method is supposed to return as a String:
public static IEnumerable<String> AccountNames() {
//TODO: Move it into Settings/Config...
String connectionString = #"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Users.mdf;Integrated Security=True;Connect Timeout=30";
// Dispose (via using) all Disposable...
using (SqlConnection connection = new SqlConnection(connectionString)) {
connection.Open();
// Dispose: prevent resource leakage...
using (SqlCommand command = new SqlCommand("SelectAllUsers", connection)) {
using (SqlDataReader usersReader = command.ExecuteReader()) {
while (usersReader.Read())
yield return (string)usersReader["Username"];
}
}
}
}
// returns selected profile
// or null if no profile was seelcted
public static string SelectProfile() {
// var: You need Select_Profile, not just a Form, right?
// again (using): don't forget to clear up the resources
using (var selectProfile = new Select_Profile()) {
// Providing that comboboxWrapper is public (bad practice)
// or SelectProfile() is implemented within Select_Profile class (good one)
selectProfile.comboboxWrapper.Items.AddRange(AccountNames());
if (selectProfile.comboboxWrapper.Items.Count > 0)
selectProfile.comboboxWrapper.SelectedIndex = 0;
if (selectProfile.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
if (selectProfile.comboboxWrapper.SelectedIndex < 0)
return null; // No item to select
else
selectProfile.comboboxWrapper.SelectedItem.ToString();
}
else
return null; // Just closed
}
}

Powershell module: Dynamic mandatory hierarchical parameters

So what I really want is somewhat usable tab completion in a PS module.
ValidateSet seems to be the way to go here.
Unfortunately my data is dynamic, so I cannot annotate the parameter with all valid values upfront.
DynamicParameters/IDynamicParameters seems to be the solution for that problem.
Putting these things together (and reducing my failure to a simple test case) we end up with:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Management.Automation;
using System.Text;
using System.Threading.Tasks;
namespace PSDummy
{
[Cmdlet(VerbsCommon.Get, "BookDetails")]
public class GetBookDetails : Cmdlet, IDynamicParameters
{
IDictionary<string, string[]> m_dummyData = new Dictionary<string, string[]> {
{"Terry Pratchett", new [] {"Small Gods", "Mort", "Eric"}},
{"Douglas Adams", new [] {"Hitchhiker's Guide", "The Meaning of Liff"}}
};
private RuntimeDefinedParameter m_authorParameter;
private RuntimeDefinedParameter m_bookParameter;
protected override void ProcessRecord()
{
// Do stuff here..
}
public object GetDynamicParameters()
{
var parameters = new RuntimeDefinedParameterDictionary();
m_authorParameter = CreateAuthorParameter();
m_bookParameter = CreateBookParameter();
parameters.Add(m_authorParameter.Name, m_authorParameter);
parameters.Add(m_bookParameter.Name, m_bookParameter);
return parameters;
}
private RuntimeDefinedParameter CreateAuthorParameter()
{
var p = new RuntimeDefinedParameter(
"Author",
typeof(string),
new Collection<Attribute>
{
new ParameterAttribute {
ParameterSetName = "BookStuff",
Position = 0,
Mandatory = true
},
new ValidateSetAttribute(m_dummyData.Keys.ToArray()),
new ValidateNotNullOrEmptyAttribute()
});
// Actually this is always mandatory, but sometimes I can fall back to a default
// value. How? p.Value = mydefault?
return p;
}
private RuntimeDefinedParameter CreateBookParameter()
{
// How to define a ValidateSet based on the parameter value for
// author?
var p = new RuntimeDefinedParameter(
"Book",
typeof(string),
new Collection<Attribute>
{
new ParameterAttribute {
ParameterSetName = "BookStuff",
Position = 1,
Mandatory = true
},
new ValidateSetAttribute(new string[1] { string.Empty }/* cannot fill this, because I cannot access the author */),
new ValidateNotNullOrEmptyAttribute()
});
return p;
}
}
}
Unfortunately this tiny snippet causes a lot of issues already. Ordered descending:
I fail to see how I can create a connection between the parameters. If you pick an author, you should only be able to pick a book that matches the author. So far GetDynamicParameters() always seems stateless though: I see no way to access the value of a different/earlier dynamic parameter. Tried keeping it in a field, tried searching MyInvocation - no luck. Is that even possible?
How do you define a default value for mandatory parameter? Doesn't fit the silly example, but let's say you can store your favorite author. From now on I want to default to that author, but having a pointer to an author is still mandatory. Either you gave me a default (and can still specify something else) or you need to be explicit.
Tab completion for strings with spaces seems weird/broken/limited - because it doesn't enclose the value with quotes (like cmd.exe would do, for example, if you type dir C:\Program <tab>). So tab completion actually breaks the invocation (if the issues above would be resolved, Get-BookDetails Ter<tab> would/will expand to Get-BookDetails Terry Pratchett which puts the last name in parameter position 1 aka 'book'.
Shouldn't be so hard, surely someone did something similar already?
Update: After another good day of tinkering and fooling around I don't see a way to make this work. The commandlet is stateless and will be instantiated over and over again. At the point in time when I can define dynamic parameters (GetDynamicParameters) I cannot access their (current) values/see what they'd be bound to - e.g. MyInvocation.BoundParameters is zero. I'll leave the question open, but it seems as if this just isn't supported. All the examples I see add a dynamic parameter based on the value of a static one - and that's not relevant here. Bugger.
I think this works. Unfortunately, it uses reflection to get at some of the cmdlet's private members for your first bullet. I got the idea from Garrett Serack. I'm not sure if I completely understood how to do the default author, so I made it so that the last valid author is stored in a static field so you don't need -Author the next time.
Here's the code:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Management.Automation;
using System.Text;
using System.Threading.Tasks;
namespace PSDummy
{
internal class DynParamQuotedString {
/*
This works around the PowerShell bug where ValidateSet values aren't quoted when necessary, and
adding the quotes breaks it. Example:
ValidateSet valid values = 'Test string' (The quotes are part of the string)
PowerShell parameter binding would interperet that as [Test string] (no single quotes), which wouldn't match
the valid value (which has the quotes). If you make the parameter a DynParamQuotedString, though,
the parameter binder will coerce [Test string] into an instance of DynParamQuotedString, and the binder will
call ToString() on the object, which will add the quotes back in.
*/
internal static string DefaultQuoteCharacter = "'";
public DynParamQuotedString(string quotedString) : this(quotedString, DefaultQuoteCharacter) {}
public DynParamQuotedString(string quotedString, string quoteCharacter) {
OriginalString = quotedString;
_quoteCharacter = quoteCharacter;
}
public string OriginalString { get; set; }
string _quoteCharacter;
public override string ToString() {
// I'm sure this is missing some other characters that need to be escaped. Feel free to add more:
if (System.Text.RegularExpressions.Regex.IsMatch(OriginalString, #"\s|\(|\)|""|'")) {
return string.Format("{1}{0}{1}", OriginalString.Replace(_quoteCharacter, string.Format("{0}{0}", _quoteCharacter)), _quoteCharacter);
}
else {
return OriginalString;
}
}
public static string[] GetQuotedStrings(IEnumerable<string> values) {
var returnList = new List<string>();
foreach (string currentValue in values) {
returnList.Add((new DynParamQuotedString(currentValue)).ToString());
}
return returnList.ToArray();
}
}
[Cmdlet(VerbsCommon.Get, "BookDetails")]
public class GetBookDetails : PSCmdlet, IDynamicParameters
{
IDictionary<string, string[]> m_dummyData = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase) {
{"Terry Pratchett", new [] {"Small Gods", "Mort", "Eric"}},
{"Douglas Adams", new [] {"Hitchhiker's Guide", "The Meaning of Liff"}},
{"An 'Author' (notice the ')", new [] {"A \"book\"", "Another 'book'","NoSpace(ButCharacterThatShouldBeEscaped)", "NoSpace'Quoted'", "NoSpace\"Quoted\""}} // Test value I added
};
protected override void ProcessRecord()
{
WriteObject(string.Format("Author = {0}", _author));
WriteObject(string.Format("Book = {0}", ((DynParamQuotedString) MyInvocation.BoundParameters["Book"]).OriginalString));
}
// Making this static means it should keep track of the last author used
static string _author;
public object GetDynamicParameters()
{
// Get 'Author' if found, otherwise get first unnamed value
string author = GetUnboundValue("Author", 0) as string;
if (!string.IsNullOrEmpty(author)) {
_author = author.Trim('\'').Replace(
string.Format("{0}{0}", DynParamQuotedString.DefaultQuoteCharacter),
DynParamQuotedString.DefaultQuoteCharacter
);
}
var parameters = new RuntimeDefinedParameterDictionary();
bool isAuthorParamMandatory = true;
if (!string.IsNullOrEmpty(_author) && m_dummyData.ContainsKey(_author)) {
isAuthorParamMandatory = false;
var m_bookParameter = new RuntimeDefinedParameter(
"Book",
typeof(DynParamQuotedString),
new Collection<Attribute>
{
new ParameterAttribute {
ParameterSetName = "BookStuff",
Position = 1,
Mandatory = true
},
new ValidateSetAttribute(DynParamQuotedString.GetQuotedStrings(m_dummyData[_author])),
new ValidateNotNullOrEmptyAttribute()
}
);
parameters.Add(m_bookParameter.Name, m_bookParameter);
}
// Create author parameter. Parameter isn't mandatory if _author
// has a valid author in it
var m_authorParameter = new RuntimeDefinedParameter(
"Author",
typeof(DynParamQuotedString),
new Collection<Attribute>
{
new ParameterAttribute {
ParameterSetName = "BookStuff",
Position = 0,
Mandatory = isAuthorParamMandatory
},
new ValidateSetAttribute(DynParamQuotedString.GetQuotedStrings(m_dummyData.Keys.ToArray())),
new ValidateNotNullOrEmptyAttribute()
}
);
parameters.Add(m_authorParameter.Name, m_authorParameter);
return parameters;
}
/*
TryGetProperty() and GetUnboundValue() are from here: https://gist.github.com/fearthecowboy/1936f841d3a81710ae87
Source created a dictionary for all unbound values; I had issues getting ValidateSet on Author parameter to work
if I used that directly for some reason, but changing it into a function to get a specific parameter seems to work
*/
object TryGetProperty(object instance, string fieldName) {
var bindingFlags = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public;
// any access of a null object returns null.
if (instance == null || string.IsNullOrEmpty(fieldName)) {
return null;
}
var propertyInfo = instance.GetType().GetProperty(fieldName, bindingFlags);
if (propertyInfo != null) {
try {
return propertyInfo.GetValue(instance, null);
}
catch {
}
}
// maybe it's a field
var fieldInfo = instance.GetType().GetField(fieldName, bindingFlags);
if (fieldInfo!= null) {
try {
return fieldInfo.GetValue(instance);
}
catch {
}
}
// no match, return null.
return null;
}
object GetUnboundValue(string paramName) {
return GetUnboundValue(paramName, -1);
}
object GetUnboundValue(string paramName, int unnamedPosition) {
// If paramName isn't found, value at unnamedPosition will be returned instead
var context = TryGetProperty(this, "Context");
var processor = TryGetProperty(context, "CurrentCommandProcessor");
var parameterBinder = TryGetProperty(processor, "CmdletParameterBinderController");
var args = TryGetProperty(parameterBinder, "UnboundArguments") as System.Collections.IEnumerable;
if (args != null) {
var currentParameterName = string.Empty;
object unnamedValue = null;
int i = 0;
foreach (var arg in args) {
var isParameterName = TryGetProperty(arg, "ParameterNameSpecified");
if (isParameterName != null && true.Equals(isParameterName)) {
string parameterName = TryGetProperty(arg, "ParameterName") as string;
currentParameterName = parameterName;
continue;
}
// Treat as a value:
var parameterValue = TryGetProperty(arg, "ArgumentValue");
if (currentParameterName != string.Empty) {
// Found currentParameterName's value. If it matches paramName, return
// it
if (currentParameterName.Equals(paramName, StringComparison.OrdinalIgnoreCase)) {
return parameterValue;
}
}
else if (i++ == unnamedPosition) {
unnamedValue = parameterValue; // Save this for later in case paramName isn't found
}
// Found a value, so currentParameterName needs to be cleared
currentParameterName = string.Empty;
}
if (unnamedValue != null) {
return unnamedValue;
}
}
return null;
}
}
}

How do I pass a string to a function requiring an Object?

I am using Chello (the c# wrapper for the Trello API). I need to pass the argument "createCard" as per the documentation here: https://trello.com/docs/api/card/index.html
And this is the function I am using from Chello:
public IEnumerable<CardUpdateAction> ForCard(string cardId, object args)
{
string queryString = BuildQueryString(args);
return GetRequest<List<CardUpdateAction>>("/cards/{0}/actions?{1}", cardId, queryString);
}
I have tried calling this in this way:
List<CardUpdateAction> cua = chello.CardUpdates.ForCard("5264d37736695b2821001d7a","createCard").ToList();
but I get the error: Parameter Count Mismatch
on this function:
protected static string BuildQueryString(object args)
{
string queryString = String.Empty;
if (args != null)
{
StringBuilder sb = new StringBuilder();
foreach (var prop in args.GetType().GetProperties())
{
sb.AppendFormat("{0}={1}&", prop.Name, prop.GetValue(args, null));
}
if (sb.Length > 0) sb.Remove(sb.Length - 1, 1);
queryString = sb.ToString();
}
return queryString;
}
The problem is the fact that your API you are using expects you to pass in a class that has public properties equal to the tags you want to use.
This is very easy to do using Anonymous Types (I am doing a slightly different example to help illustrate a point)
//This will cause BuildQueryString to return "actions=createCard&action_fields=data,type,date"
var options = new { actions = "createCard", action_fields = "data,type,date" };
List<CardUpdateAction> cua = chello.CardUpdates.ForCard("5264d37736695b2821001d7a",options).ToList();
string is an object. Every type in .NET platform inherits from Object. This is called Unified Type System.
On the other hand, we have the Liskov Substitution Principle, which put simply, says that if B is a subtype of A (B is A), then you should be able to use B, wherever A is used.
Based on these reasons, you can pass string to any method that accepts an object as an argument.
You can test it:
public void DoSomething(object args)
{
}
public void Main()
{
DoSomething("some string argument, instead of the object");
}
It works just fine. No error.

Trying to iterate through ListBox, Error : Specified cast is not valid

I have a method in another class i'm using to send data to a database. That method is here as well.
public Int32 AddOrder(clsStock NewItem)
{
//this function takes the data passed via NewItem
//and passes it to the parameters for the stored procedure
//
//create an instance of the data dictionary
clsDataDictionary DD = new clsDataDictionary();
//create an instance of the object class
Int32 ReturnValue;
//create an instance of the data conduit
clsDataConduit Items = new clsDataConduit();
//pass the data for this address
Items.AddParameter(DD.sproc_tblOrders_Add_AuthId, NewItem.AuthId);
Items.AddParameter(DD.sproc_tblOrders_Add_ItemId, NewItem.ItemId);
Items.AddParameter(DD.sproc_tblOrders_Add_DateOrdered, NewItem.DateOrdered);
Items.AddParameter(DD.sproc_tblOrders_Add_Cancel, NewItem.Cancel);
//execute the stored procedure
ReturnValue = Items.Execute(DD.sproc_tblOrders_Add);
//return the primary key value
return ReturnValue;
}
The method on my aspx page which i'm using to iterate through my listbox and execute that method for each item in the listbox is here as well.
protected void btnSubmit_Click1(object sender, EventArgs e)
{
//create an instance of the collection class
clsStockCollection Items = new clsStockCollection();
foreach(int id in lstAdded.Items)
{
TheItem.AuthId = 5;
TheItem.ItemId = Convert.ToInt32(lstAdded.Items[id].Value);
TheItem.Cancel = "false";
Items.AddOrder(TheItem);
}
Response.Redirect("Order.aspx");
}
When I run my website and hit the btnSubmit it's giving the following error :
"Specified cast is not valid" that is on the method on the aspx page (the 2nd pastebin file)
Any idea why this is?
It should be like this
foreach(ListItem item in lstAdded.Items)
{
TheItem = new clsStock();
TheItem.AuthId = 5;
TheItem.ItemId = Convert.ToInt32(item.Value);
TheItem.Cancel = "false";
Items.AddOrder(TheItem);
}
You are iterating the ListBox.Items through an int type field. ListBox.Items is a ListItemCollection, what you can do is use implicitly typed variable using var keyword, like:
foreach(var id in lstAdded.Items)
{
TheItem.AuthId = 5;
TheItem.ItemId = Convert.ToInt32(id.Text); //Change here
TheItem.Cancel = "false";
Items.AddOrder(TheItem);
}
Currently it appears you are considering it as an index in foreach loop, instead its a single item from the lstAdded

Categories

Resources