I'm developing a SSIS control flow task. On my UI I have a combobox which displays a list of avaialble user variables as well as the ability add a new variable. I'm able to add the variable successfully but I can't see it in my combobox even after I repopulate the datasource. On the SelectionChangeCommitted event I am saving the combobox selection. If the user selects to add a new SSIS user variable then they are prompted to within this method. The variable is saved and then I am repopulating the datasource of the combobox. Although my new variable isn't being shown in the drop down list. Should I be repopulating the combobox on a different event?
An example of the code I am using below.
private List<string> FillVariablesList()
{
List<string> Variables = new List<string>();
Variables.Add("");
Variables.Add(New_Variable);
foreach (Variable v in this.theTaskHost.Variables)
{
if (!v.SystemVariable && v.DataType == TypeCode.String)
Variables.Add(v.Name);
}
return Variables;
}
combobox.datasource = FillVariablesList();
Try using a shared ObservableCollection like this.
...
class A
{
private ObservableCollection<string> variables = new ObservableCollection<string>();
...
private void FillVariablesList()
{
variables.Clear();
variables.Add("");
variables.Add(New_Variable);
foreach (Variable v in this.theTaskHost.Variables)
{
if (!v.SystemVariable && v.DataType == TypeCode.String)
variables.Add(v.Name);
}
this.comboBox.DataSource = null;
this.comboBox.DataSource = variables;
}
}
And you can even setup the FillVariables method so that it just adds the new one rather than clearing it and re-filling - I just don't know how the rest of your code is structured.
Related
I am a not experienced programmer, just a rookie enthusiast.
I have a webForm where I add items to a drop-down list.
There is another webform that contains another drop-down list, I want this second "ddl" to display the items I added to the "first ddl".
After not succeeding with public properties, I tried to get this accomplished in the most straight fashion:
In designer.cs change the first "ddl" from protected global to public.
On the second webForm I wrote:
WebForm3 wf_ConfigurationPage = new WebForm3();
And a short function with these lines:
ddl_ingenieros.DataSource = wf_ConfigurationPage.ddl_Engineers;
ddl_ingenieros.DataBind();
I am calling the function from PageLoad but unfortunately the "ddl" is not showing the items from its "DataSource ddl".
Also, when I switch pages, the items I added to the original "ddl" just disappear.
Can you help me get these 2 issues resolved?
I managed to get something similiar done for a gridview as follows:
On the webform where the original gridview is located:
static DataSet DS;
static DataTable tableRequests;
/* -------------- Public Properties ---------------- */
public DataSet currentList //Allows access from other pages.
{
get {
return DS;
}
}
public DataTable currentTable {
get {
return tableRequests;
}
}
On the second webForm I wanted to show the gridview:
WebForm1 wf_ActiveReq = new WebForm1();
Then a short function that I call from PageLoad, which has these lines:
gv_results.DataSource = wf_ActiveReq.currentList;
gv_results.DataBind();
I was unable to do the same with the ddls because unlike the DataSet and the Data Table, the ddl was created from designer view, when I tried to declared them in the "code behind" of the webForm where the "original" ddl exists I got an error about the object being duplicate, which makes sense.
Thanks for your time
#Erkaner
In first webForm:
static List<string> myItems = new List<string>();
protected void btn_add_Click(object sender, EventArgs e)
{
if (Session["myItems"] != null)
{
myItems = (List<string>) Session["myItems"];
}
myItems.Add(txt_newAdmin.Text);
ddl_Engineers.DataSource = myItems;
ddl_Engineers.DataBind();
txt_newAdmin.Text = "";
}
In second webForm, I wrote a function I call from pageLoad:
private void pull_engineersList()
{
ddl_ingenieros.DataSource = Session["myItems"];
ddl_ingenieros.DataBind();
}
Thanks again!
Why not use Session :
In the first page:
Session["myddlstore"] = myFirstDDL.DataSource;
and in the second page
mySecondDDL.DataSource = Session["myddlstore"];
mySecondDDL.DataBind();
UPDATE
If the dropdowlinst items are added by the user, then you can implement something like this in the button click that adds item to the dropdownlist:
List<string> myitems = new List<string> ();
if(Session["myitems"] != null)
{
myitems = (List<string>) Session["myitems"];
}
myitems.Add(txt_NewItem.Text);
myFirstDDL.DataSource = myitems;
myFirstDDL.DataBind();
and, similarly. in the second page
mySecondDDL.DataSource = Session["myitems"];
mySecondDDL.DataBind();
Session["myitems"] = myitems;
If you store a more complex object in dropdownlist, I would define a class that represents the complex object, and still use the approach described above (List<ObjectType>).
I have class say class A and i have cintialised a list (I am using HashSet) in the costructor so as to have its access throught out the program.
I Add the item in the list inside the Loaded event of comboBox. Ans i use that saved list after the loaded event I found that it do not contain the data i added.
Is this thing normal with loaded event ? Could some one please tell me way to save data added inside the List (I am using HashSet) in loaded event?
My code is :
static HashSet < string > listOfUpdatedUIElement = new HashSet < string > ();
static HashSet < string > storeUpdatedUIElement = new HashSet < string > ();
//This in constructor
GenerateParametersPreview()
{
storeUpdatedUIElement = null;
}
public Grid simeFunction() {
ComboBox cmb = new ComboBox();
cmb.Loaded += (o3, e) => {
foreach(string atrb in listOfUpdatedUIElement) //I have seen on debugging the data are updated in listOfUpdatedUIElement
{
storeUpdatedUIElement.Add(atrb);
}
};
foreach(string atrb in storeUpdatedUIElement) //Here storeUpdatedUIElement hashset contains nothing inside
{
cmb.Items.Add(atrb);
}
Grid.SetColumn(cmb, 1);
comboRowGrid.Children.Add(cmb);
Grid.SetRow(comboRowGrid, 0);
bigGrid.Children.Add(comboRowGrid); //suppose ihad created this bigGrid and it will dispaly my comboBox
return (bigGrid);
}
The events are the main tool of the Event-driven-programming paradigm.
In event driven programming you are not sure when and whether at all some condition changes (like some ComboBox is finally loaded or not), you are reacting to the notification about that change - raised event.
It means that
cmb.Loaded += (o3, e) =>
{
foreach(string atrb in listOfUpdatedUIElement)//I have seen on debugging the data are updated in listOfUpdatedUIElement
{
storeUpdatedUIElement.Add(atrb);
}
};
won't(at least it is hardly possible) execute before the
foreach(string atrb in storeUpdatedUIElement) //Here storeUpdatedUIElement hashset contains nothing inside
{
cmb.Items.Add(atrb);
}
That's why the storeUpdatedUIElement is empty when the loop enumerates it.
SOLUTION:
So, if you want to update your ComboBox items on Loaded event you should put all the relevant code inside the event:
cmb.Loaded += (o3, e) =>
{
foreach(string atrb in listOfUpdatedUIElement)//I have seen on debugging the data are updated in listOfUpdatedUIElement
{
storeUpdatedUIElement.Add(atrb);
}
foreach(string atrb in storeUpdatedUIElement) //Here storeUpdatedUIElement hashset contains nothing inside
{
cmb.Items.Add(atrb);
}
};
P.S.: In such a case you should probably unite those two loops in one:
foreach(string atrb in listOfUpdatedUIElement)//I have seen on debugging the data are updated in listOfUpdatedUIElement
{
storeUpdatedUIElement.Add(atrb); // Remove it too if it is not used anywhere else
cmb.Items.Add(atrb);
}
simeFunction is working using a new new combobox that is never added to your form.
You are expecting your list to be populated when this combobox is loaded and since it is never added to your form, it never will be loaded.
Please forgive me for such a stupid question. I am sure many of you will find this easy, where I have sent almost half the day reading trying to figure this out.
Here is the problem:
I have a FORM (Form1.cs) made. In that form I created a listview, and named it "ListView1".
Within the Form1.cs, I call a function called FileManager(this), where I pass in the THIS object.
In FileManager.cs I was able to listviewArray= originalForm.Controls.Find("listView1", true) and find that 'listview'.
When I do a listviewArray[0]<-- I can't seem to add a list to it.
FileManager.cs
FileManager(object sender)
{
if (sender != null)
{
originalForm = (Form)sender;
}
}
public void getFiles()
{
filePaths = Directory.GetFiles(hsocDir);
if(filePaths != null)
{
listviewArray= originalForm.Controls.Find("listView1", true);
if(listviewArray != null)
{
ListViewItem lvi = new ListViewItem("text");
// My Array is listViewArray
// How to add things to Lvi to it.
}
}
== Form1.cs
public Form1()
{
InitializeComponent(`enter code here`);
mysql = new MySQLCheck(this);
fileManager = new FileManager(this);
fileManager.getFiles();
}
You can't access element 0 of the collection because the collection is empty. To add an item, use:
listViewArray.Items.Add(lvi);
You need to modify the Items collection instead of the ListView itself for this to work, as ListView is not a collection (its a control).
listViewArray.Items.Add(lvi);
Also in your listview,setting this properties will help :
// Set the view to show details.
listViewArray.View = View.Details;
// Select the item and subitems when selection is made.
listViewArray.FullRowSelect = true;
// Display grid lines.
listViewArray.GridLines = true;
I have a BindingList< KeyValuePair < string, string > > that is bound to a ComboBox control. Based on some conditions, the BindingList will be added a new KeyValuePair. Now, the Newly added item shows up at index 0 of the Combobox, instead of at the end.
While debugging, I found that the BindingList has got the right order. (i.e, the new KeyValuePair is appended)
Also, I check the SelectedValue of the ComboBox in it's SelectedIndexChanged handler and it seems to be not of the ListItem that got selected. Instead, it is that of the supposed ListItem, if the ComboBox had got the right order as in its DataSource, - the BindingList..
The code is a small part of a large project.. Plz let me know if the question is not clear. I can put the relevant parts of the code as per our context.
How could something like this happen? What can I do differently?
I have this class something like this.
public class DropdownEntity
{
//removed all except one members and properties
private string frontEndName
public string FrontEndName
{
get {return this.frontEndName; }
set {this.frontEndName= value; }
}
//One Constructor
public DropdownEntity(string _frontEndName)
{
this.FrontEndName = _frontEndName;
//Removed code which initializes several members...
}
//All methods removed..
public override string ToString()
{
return frontEndName;
}
}
In my windows form, I have a tab control with several tabs. In one of the tabs pages, I have a DataGridView. The user is supposed to edit the cells and click on a Next - button. Then, some processing will be done, and the TabControl will be navigated to the next tab page.
The next tab page has the combobox that has the problem I mentioned. This page also has a back button, which will take back.. the user can modify the gridview cells again.. and click on the next button. This is when the order gets messed up.
I am posting here the Click event handler of the Next Button.. Along with the class, with the rest of the code removed.
public partial class AddUpdateWizard : Form
{
//Removed all members..
BindingList<KeyValuePair<string, string>> DropdownsCollection;
Dictionary<string, DropdownEntity> DropdownsDict;
//Defined in a partial definition of the class..
DataGridView SPInsertGridView = new DataGridView();
ComboBox DropdownsCmbBox = new ComboBox();
Button NextBtn2 = new Button();
Button BackBtn3 = new Button();
//Of course these controls are added to one of the panels
public AddUpdateWizard(MainForm mainForm)
{
InitializeComponent();
DropdownsDict = new Dictionary<string, DropdownEntity>();
}
private void NextBtn2_Click(object sender, EventArgs e)
{
string sqlArgName;
string frontEndName;
string fieldType;
for (int i = 0; i < SPInsertGridView.Rows.Count; i++)
{
sqlArgName = "";
frontEndName = "";
fieldType = "";
sqlArgName = SPInsertGridView.Rows[i].Cells["InsertArgName"].Value.ToString().Trim();
if (SPInsertGridView.Rows[i].Cells["InsertArgFrontEndName"].Value != null)
{
frontEndName = SPInsertGridView.Rows[i].Cells["InsertArgFrontEndName"].Value.ToString().Trim();
}
if (SPInsertGridView.Rows[i].Cells["InsertArgFieldType"].Value != null)
{
fieldType = SPInsertGridView.Rows[i].Cells["InsertArgFieldType"].Value.ToString().Trim();
}
//I could have used an enum here, but this is better.. for many reasons.
if (fieldType == "DROPDOWN")
{
if (!DropdownsDict.ContainsKey(sqlArgName))
DropdownsDict.Add(sqlArgName, new DropdownEntity(frontEndName));
else
DropdownsDict[sqlArgName].FrontEndName = frontEndName;
}
else
{
if (fieldType == "NONE")
nonFieldCount++;
if (DropdownsDict.ContainsKey(sqlArgName))
{
DropdownsDict.Remove(sqlArgName);
}
}
}
//DropdownsCollection is a BindingList<KeyValuePair<string, string>>.
//key in the BindingList KeyValuePair will be that of the dictionary.
//The value will be from the ToString() function of the object in the Dictionary.
DropdownsCollection = new BindingList<KeyValuePair<string,string>>(DropdownsDict.Select(kvp => new KeyValuePair<string, string>(kvp.Key, kvp.Value.ToString())).ToList());
DropdownsCmbBox.DataSource = DropdownsCollection;
DropdownsCmbBox.DisplayMember = "Value";
DropdownsCmbBox.ValueMember = "Key";
//Go to the next tab
hiddenVirtualTabs1.SelectedIndex++;
}
private void BackBtn3_Click(object sender, EventArgs e)
{
hiddenVirtualTabs1.SelectedIndex--;
}
//On Selected Index Changed of the mentioned Combobox..
private void DropdownsCmbBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (DropdownsCmbBox.SelectedValue != null)
{
if (DropdownsDict.ContainsKey((DropdownsCmbBox.SelectedValue.ToString())))
{
var dropdownEntity = DropdownsDict[DropdownsCmbBox.SelectedValue.ToString()];
DropdownEntityGB.Text = "Populate Dropdowns - " + dropdownEntity.ToString();
//Rest of the code here..
//I see that the Datasource of this ComboBox has got the items in the right order.
// The Combobox's SelectedValue is not that of the selected item. Very Strange behavior!!
}
}
}
}
The very first time the user clicks the Next Button, it's fine. But if he clicks the Back Button again and changes the Data Grid View cells.. The order will be gone.
I know, it can be frustrating to look at. It's a huge thing to ask for help. Any help would be greatly appreciated!
Please let me know if you need elaboration at any part.
Thanks a lot :)
I think you have two problems here.
First, if you want to retain the order of the items you should use an OrderedDictionary instead of a regular one. A normal collection will not retain the order of the items when you use Remove method. You can see more info about this related to List here.
You could use such dictionary like this:
DropDownDict = new OrderedDictionary();
// Add method will work as expected (as you have it now)
// Below you have to cast it before using Select
DropDownCollection = new BindingList<KeyValuePair<string, string>>(DropDownDict.Cast<DictionaryEntry>().Select(kvp => new KeyValuePair<string, string>(kvp.Key.ToString(), kvp.Value.ToString())).ToList());
The second problem could be that you change the display name (FrontEndName) of already existing items, but the key is preserved. When you add a new item, try to remove the old one that you're not using anymore and add a new item.
The Sorted Property of the Combobox is set to True! I didn't check that until now. I messed up. Terribly sorry for wasting your time Adrian. Thanks a lot for putting up with my mess here.. :)
I have a method that adds items to my listbox called refreshInterface which is called as soon as the programe starts, adding names of homeforms in the listbox using the FormItems class, here is the rereshInterface method below
public void refreshInterface()
{
//int number = 0;
foreach (DataSet1.xspGetAnalysisUsageTypesRow homeForms in myDataSet.xspGetAnalysisUsageTypes)
{
var forms = new FormItems(homeForms);
listBox1.Items.Add(forms);
}
}
The FormItems class is this below
public class FormItems
{
public DataSet1.xspGetAnalysisUsageTypesRow types { get; set; }
public FormItems(DataSet1.xspGetAnalysisUsageTypesRow usageTypes)
{
types = usageTypes;
}
public override string ToString()
{
// returns the rows that are relating to types.xlib_ID
var libtyps = types.GetxAnalysisUsageRows();
var cnt = 0;
foreach (DataSet1.xAnalysisUsageRow ty in libtyps)
{
//returns true if ty is null
bool typeNull = ty.Isxanu_DefaultNull();
// if its false, if xanu_Default is set
if (!typeNull)
{
cnt += 1;
}
}
var ret = String.Format("set {0} [Set: {1}]", types.xlib_Desc, cnt);
//return this.types.xlib_Desc;
return ret;
}
}
Each listbox (the listbox is on the left of the homeform) item has a number of reports that can be added to it, so for instance, i select an homeform from my listbox, there are 12 textboxes on the right hand side and each textbox has a pair of buttons which are Browse and Clear. If I click on the browse button a new form appears, and i select a report from that form and add it to a particular textbox, the count for that homeform should update, and i clear a textbox for a particular homeform, the count should also update.
At the moment when i debug the application, it shows me the count of each Homeform depending on the amount of reports added to the homeform, but while the programe is running, if i add a new report to a homeform, the count does not update until i restart the debug session. I was told about using a Databinding method but not sure of how i could use it here
How do i ge my listbox item to update ?
You should probably look into binding. Here is a good place to start:
http://www.codeproject.com/Articles/140621/WPF-Tutorial-Concept-Binding
If you want a GUI to respond to data changes then binding is your best friend.
You should bind List Box component source to Observable Collection, every update you do to Observable Collection will update List Box data.
Might not be exact but should give you an idea.
public void refreshInterface()
{
Dictionary<int,string> items = new Dictionary<int,string>();
//int number = 0;
foreach (DataSet1.xspGetAnalysisUsageTypesRow homeForms in myDataSet.xspGetAnalysisUsageTypes)
{
var formitem = new FormItems(homeForms);
items.Add(formitem.someprop, formitem.toString());
}
listbox.DataSource = items;
listbox.DisplayMember = "Value";
listbox.ValueMember = "Key";
}