I promise that I did search this issue before posting. :) It may have also been answered but maybe in a different context which I could not properly understand. The closest one that I think sort-of matches my query is this: get-eventhandler-by-name. Again, I am new to this and I am just learning as I go so please bear with me.
Anyway, my query is I have several dynamically created controls with IDs taken from a database. Now I want to attach these controls to its related events (mostly DropDown_SelectedIndexChanged) by looping through my database and creating the events by passing a string. Hence:
ddl.SelectedIndexChanged += new EventHandler(string);
Earlier I was hardcoding it with ifs like so:
if (ddl.ID == "brandCode")
{
ddl.SelectedIndexChanged += new EventHandler(brandCode_SelectedIndexChanged);
}
which will obviously work but it's not really dynamic.
And lol I even tried:
ddl.SelectedIndexChanged += new EventHandler(dr["AspId"].ToString().Trim());
which is obviously wrong because it is passing a string instead of an object.
Disclaimer. This question is related to my earlier post Dynamically created cascading dropdown lists
I'd like to create a new field on an existing document. I'm using the following line to get all the documents out of the database into POCOs:
var collection = _database.GetCollection<Address>(collectionName);
I then make some changes to each and save them back into the database using this line:
collection.ReplaceOne(
filter: new BsonDocument("_id", a.id),
options: new UpdateOptions { IsUpsert = true },
replacement: a);
That all works nicely.
To add a field, I've tried the following:
a.ToBsonDocument().Add("RainfallMM", rainfallMM);
But it doesn't make it to the database. Is there a trick to it?
I asked you in comment did you add new property to address model and you said you didn't and you want to add it dynamically. Trick here is you initialize your collection as collection of addresses and mongo ignores all properties that are not part of address model by default.
If you want to add it dynamically you need to change how you start your collection to:
var collection = _database.GetCollection<BsonDocument>("addresses");
Now your collection is not tied to address model and you can work with it as you wish. Everything is BSON document now!
For example you can do this:
var inserted = MongoCollection.Find(x => true).FirstOrDefault();
inserted.Add(new BsonElement("RainfallMM", rainfallMM);
MongoCollection.ReplaceOne(new BsonDocument("_id", inserted["_id"]), inserted);
PS there are some other workarounds and if this one you don't like I can show you the rest =)
Hope it helps! Cheers!
As #Fidel asked me to I will try to briefly summarize other solutions. The problem in accepted answer is that while it works it loses it's connection to Address model and OP is stuck with working with BSON documents.
IMO working with plain BSON documents is pain.
If he ever wishes to change back to initializing collection as collection of Addresses and tries to get anything from db he will encounter an error saying something like:
Missing serialization information for rainfallMM
He can fix that by including tag above his Address class like this:
[BsonIgnoreExtraElements]
public class Address
{
...fluff and stuff...
}
Problem now is if he is not careful he can lose all his info in dynamically added properties.
Other problem is if he adds another property dynamically. Now he has to remember there are 2 properties which are not in model and the hell breaks loose.
Weather he likes it or not, to make his life easier he will probably have to modify Address model. There are 2 approaches and their official documentation is great (I think), so I will just link it here:
http://mongodb.github.io/mongo-csharp-driver/2.4/examples/mixing_static_and_dynamic/
IF you ask me which one is better I will honestly tell you it depends on you. From documentation you will see that if you use an extra BSON document property you don't have to worry about naming your extra properties.
That would be all I can think of now!
Hope it helps you!
try with
a.Add({"RainfallMM", rainfallMM});
I have window with a listbox bound to an ObservableCollection of People (a set of entity framework objects that I retrieve in response to a users query: a search box), i then have functions such as Edit, Delete and Add New. At the moment i am simply making sure that each time i Add or Remove something from the Database that i also work with the OC. Is there a better way of handling this?
Thanks,
Kohan.
I found that you may need to manage the OC youself when it comes to EF manipulations. For example, when you Add a new item to DB
private bool AddItems(Item item)
{
bool addSucceed = false;
// Do adding ...
if(addSucceed)
MyObservableCollection.Remove(item)
else
// Error notificaiton here.
}
Hope that helps.
I'm trying to use ASP.NET's Repeater objects to loop over properties of an object.
For example... I have an ObjectDataSource to grab object "Program" by ID...
Program has properties such as Program.Stakeholders and Program.Outcomes which are Lists of "Stakeholder" and "Outcome" objects.
Now... what I'd really like to do is use the Repeaters to target these Properties and loop over the lists they contain. However, as far as I know I'd have to set up a separate data source for each one, tied to an individual method to retrieve each list.
Can anyone provide a better way to use these Repeater objects, or point me at some resources which would help? If this doesn't make sense I can try to clarify it more.
Using the built-in ObjectDataSource mapping up a separate datasource for each item is probably the only straightforward way (and the only way that's easy enough to be worth the effort...).
Is it a requirement that you use the ObjectDataSource, or can you choose a different way to get the data from the storage? I would recommend either using Entity Framework (which imho rocks) or creating your own custom types to which you get the data with a custom designed DAL (which is a lot more work than using EF, but if you're, like some, concerned that EF is still in infancy this might be your option).
In either case, you'll end up with a C# class called Program, which has properties of type IEnumerable<Stakeholder> and IEnumerable<Outcome> called Stakeholders and Outcomes respectively. You can then use these as datasources for the item repeaters and set them in the ItemDataBound event of the ProgramRepeater, maybe something like this:
protected void ProgramRepeater_ItemDataBound(object sender, ItemDataBoundEvent e) {
Program dataItem = (Program)e.DataItem;
Repeater stakeholderRptr = (Repeater)e.Item.FindControl("ProgramRepeater");
Repeater outecomeRptr = (Repeater)e.Item.FindControl("OutcomeRepeater");
stakeholderRptr.DataSource = dataItem.Stakeholders;
stakeholderRptr.DataBind();
outecomeRptr.DataSource = dataItem.Outcomes;
outecomeRptr.DataBind();
}
This is assuming that you're using ASP.Net WebForms, of course. In ASP.Net MVC it is even easier - you just send the Program object to the View as the Model object, and loop through its Stakeholders and Outcomes in a couple of nested for loops directly on the View.
Note: All code is provided as is, and I do not guarantee that it will run as expected or even compile. It is just to give you an idea of what to make your code do - not necessarily the exact code you need to solve your problem.
I am having difficulty refreshing windows forms controls that are using a BindingSource object. We have a CAB/MVP/SCSF client that I (actually “we” since it is a team effort) are developing that will interact with WCF services running on a remote server. (This is our first attempt at this, so we are in a learning mode). One of the calls (from the Presenter) to the service returns a DataSet that contains 3 DataTables, named “Contract”, “Loan” and “Terms”. Each table contains just one row. When the service returns the dataset, we store it in the SmartPart/View in a class member variable, by calling a function in the view called BindData() and passing the dataset in to the view from the presenter class;
private System.Data.DataSet _ds = null;
public void BindData(System.Data.DataSet ds)
{
string sErr = "";
try
{
_ds = ds; // save to private member variable
// more code goes down here
}
}
We are trying to bind each of the three DataTables to an assortment of Windows Forms TextBoxes, MaskedEditBoxes, and Infragistics UltraComboEditor Dropdown comboboxes We created three BindingSource objects, one for each DataTable using the VS2008 IDE.
private System.Windows.Forms.BindingSource bindsrcContract;
private System.Windows.Forms.BindingSource bindsrcLoan;
private System.Windows.Forms.BindingSource bindsrcTerms;
We are binding the values like this
if (bindsrcContract.DataSource == null)
{
bindsrcContract.DataSource = _ds;
bindsrcContract.DataMember = “contract”;
txtContract.DataBindings.Add(new Binding("Text", bindsrcContract, "contract_id", true));
txtLateFeeAmt.DataBindings.Add(new Binding("Text", bindsrcContract, "fee_code", true));
txtPrePayPenalty.DataBindings.Add(new Binding("Text", bindsrcContract, "prepay_penalty", true));
txtLateFeeDays.DataBindings.Add(new Binding("Text", bindsrcContract, "late_days", true));
}
if (bindsrcLoan.DataSource == null)
{
bindsrcLoan.DataSource = _ds;
bindsrcLoan.DataMember = “loan”;
mskRecvDate.DataBindings.Add(new Binding("Text", bindsrcLoan, "receive_date", true));
cmboDocsRcvd.DataBindings.Add(new Binding("Value", bindsrcLoan, "docs", true));
}
This works when we do the first read from the service and get a dataset back. The information is displayed on the form's controls, we can update it using the form, and then “save” it by passing the changed values back to the WCF service.
Here is our problem. If we select a different loan key and make the same call to the service and get a new DataSet, again with 3 tables with one row each, the controls (textboxes, masked edit boxes, etc.) are not being updated with the new information. Note that the smartPart/View is not closed or anything, but remains loaded in between calls to the service. On the second call we are not rebinding the calls, but simply trying to get the data to refresh from the updated DataSet.
We have tried everything we can think of, but clearly we are missing something. This is our first attempt at using the BindingSource control. We have tried
bindsrcContract.ResetBindings(false);
and
bindsrcContract.ResetBindings(true);
and
bindsrcContract.RaiseListChangedEvents = true;
and
for (int i = 0; i < bindsrcContract.Count; i++)
{
bindsrcContract.ResetItem(i);
}
As well as resetting the DataMember property again.
bindsrcContract.DataMember = ”Contract”;
We’ve looked at a lot of examples. Many examples make reference to the BindingNavigator but since the DataTables only have one row, we did not think we needed that. There are a lot of examples for grids, but we’re not using one here. Can anyone please point out where we are going wrong, or point us to resources that will provide some more information?
We’re using VisualStudio 2008, C# and .Net 2.0, XP client, W2K3 server.
Thanks in advance
wes
I was having a similar issue today and found this works.
private void btnCancel_Click(object sender, EventArgs e)
{
this.MyTable.RejectChanges();
this.txtMyBoundTextBox.DataBindings[0].ReadValue();
this.EditState = EditStates.NotEditting;
}
The underlying problem in both your questions is that the Binding-Manager keeps the links to the original objects.
When you assign _ds as the DataSource, the Binding-Manager analyzes the DataSet and acts accordingly. If you assign some other DataSet to _ds, the Binding-Manager has no way of knowing this. It still has the reference on the original DataSet-object. So this explains why you have to reset the DataSource-property to the new DataSet.
It also explains why the removing and adding of the table doesn't lead to your expected result. Again, the Binding-Manager holds the reference to the old table (or the first row in that table). The new table is never bound. Also in this case the reassigning of _ds does not help, because _ds points to the same DataSet-object as before. The Binding-Manager is smart enough to notice that it's the same object and does no rebinding action.
You either have to modify the contents of your bound objects (which fires a PropertyChanged-Event to which the Binding-Manager subscribes) or you have to trigger a complete rebind by assigning a different object to the DataSource-property.
This is a simplified description of what actually happens, but I hope it's enough to explain and solve your problem. Unfortunately I have yet to find a comprehensive explanation of WinForms databinding on the web (or elsewhere).
Failing all else, you can reassign the DataSource every time you receive a new dataset, doing something like this:
bindsrcContract.DataSource = typeof(System.Data.DataSet);
bindsrcContract.DataSource = _ds;
(Also, initializing DataMember first and then DataSource will give you better performance.)
Wes, I'm very glad I could help. I still remember an issue very similar to yours taking me weeks to figure out in the wild...
Regarding your questions, here's all I know:
If you set the DataSource first, then the DataMember, your data source will be scanned twice, since setting the DataMember subsequently changes the existing (valid) binding. If you do it the other way around, setting DataMember first (with DataSource being null or better, typeof(YourData)), binding only takes place once when you set the DataSource.
I think you can apply the same solution here. Instead of just
bindsrcContract.DataSource = _ds;
in your last line, you should write
bindsrcContract.DataSource = typeof(System.Data.DataSet);
bindsrcContract.DataSource = _ds;
Sorry to disappoint, but I learned all I know about data binding from MSDN as well as trial-and-error. It was quite painful. Hopefully someone else can chime in with a useful link or two.
try combination :
bindingsource.EndEdit() // writting data to underlying source
bindingSource.ResetBindings(false) // force controls to reread data from bindingSource
use this whenever you write something to controls.