I am pretty new to C# and .NET and I'm strugling a little with the whole concept of databinding. What I am asking for is a quick rundown of the concept, or even better, point me towards sources on the net (preferred) or in print that can help me get my head around the idea.
EDIT:
I do my development in vs2008 and we are using winforms
Well, what architecture are you using? winforms? asp.net? wpf?
The high level is that if you have objects such as:
public class Person {
public string Name {get;set;}
public DateTime DateOfBirth {get;set;}
}
Then you can get the binding framework to do all the hard work, and you just say what you want bound - for example (winforms):
txtName.DataBindings.Add("Text", person, "Name");
This sets the textbox's Text property based on the person's Name, and can update the person's Name when the user changes the text.
Multi-record binding is more complex, and is based on IList in winforms/wpf, and IEunmerable in ASP.NET; this allows you to bind multiple records (for example into a grid). If the list offers extra features (sorting, filtering etc, via IBindingList, IBindingListView, etc), then more functionality might be available.
Binding also allows "observer" usage - i.e. change notification: if you indirectly change the person's Name, then the textbox gets automatically updated. This relies on events - either of the form public event EventHandler NameChanged;, or (more commonly now) via the INotifyPropertyChanged event (allowing one event to notify for multiple properties).
Some lists (such as BindingList<T>, DataView) have similar notification loops.
The concept of databinding is quite simple;
It allows you to 'bind' the data that is contained in an object to a visual control.
That control 'displays' your data. When the user changes the value that is displayed by the control, the changes are automatically persisted to the underlying object.
Vice versa, when someone changes the data in the object, the control can display the newest value.
http://msdn.microsoft.com/en-us/library/ms752347.aspx
http://www.akadia.com/services/dotnet_databinding.html
Related
I am having a form with different type of controls like Text Box, Drop downs, Check box, Radio buttons etc. All these controls are loaded dynamically from database at run time.
I want to perform validation on Text box on conditional basis. For example, If we have selected any value in drop down, then you must have to fill details in Text box. Otherwise text box details are not required.
I am open to use database to perform this task and I am using MVVM pattern in my project.
Any help on this is highly appreciated.
Thanks.
(I started this as a comment, but it ended up being too long).
In theory you have access to all these controls and their values in your ViewModel.
Without knowing the specifics of your program, it's difficult to suggest anything useful, but in essence you need to expose some more properties from your ViewModel (probably boolean) which will be calculated based on the values in your controls. Then you need to bind IsEnabled properties on your controls to these new properties.
Sounds simple, but I think you have some architectural problems which will make it difficult to implement what I suggested above. In order for this to work and automatically update your controls whenever other controls' content change, your ViewModel needs to implement INotifyPropertyChanged and raise PropertyChanged event every time you update one of those boolean properties.
I think what you're trying to do could be achieved with ItemsControl and DataTemplates (and maybe DataTemplateSelectors). This will allow you to store "data" in your ViewModel (say List or something more specific) without referencing the actual Controls and the relevant DataTemplates will add the right controls for different data types you have in your ViewModel.
I'm writing a custom control from scratch (using Graphics) that will represent a set of columns each of which will have a list of cells, a lot like a grid view except this will have some custom features.
I'm having a hard time trying to figure out how to manage all the data binding problem. I'd like this grid to have a DataSource property which would basically need to be a jagged array (2D) of some objects each of which would need to be bound to a cell in the control. I'm still not sure which properties each of these objects will have, and so far I'm only using text. What I've been trying to do is have my model implement this interface:
public interface IDiagramDataSource
{
IBindingList Columns { get; }
}
and then have each column implement this:
public interface IDiagramColumnDataSource : INotifyPropertyChanged
{
IBindingList Cells { get; }
}
But I'm still having a hard time figuring out the best way to keep all these objects synchronized to the corresponding objects in my grid. I'd love to be able to put all the binding mess in an independent class but not sure how to do this. For now I'll just repaint the whole thing whenever there is any change in the data source, but I'd like to eventually be able to identify which property in which cell or which cell in which column have changed so that I can update only the necessary items in my grid.
Is there any pattern to follow when you want a control to be bindable to nested lists? I'm guessing there is since the DataGridView control does this.
I would suggest 2 option:
First suggestion has been suggested by HighCore, is to using WPF rather than custom winform object to do the job. WPF also has much more controls (ListView, even the generic ItemContainer, if I am not mistaken). Just implement the INotifyPropertyChanged at the ViewModel, then call OnPropertyChanged for the root (aggregate) element everytime you need to refresh the control. Don't forget to add UpdateSourceTrigger for ItemsSource Binding. WPF controls also has good implementation for drag and drop function.
I won't detail the implementation in WPF since there are much articles explaining it.
However if you think that it must be done with custom graphic drawing, then it is quite complex. You must trigger the method to re-draw your control graphic everytime any changes occured in the item list for it to take effect. It will be better if you can do partial update to your graphic (maybe using panels to trick it), but it is harder.
If not handled correctly (moreover if your control contains huge amount of data and/or control size) then it can causes some high memory loads.
I'm currently trying to develop a small finance application. My application needs a quite complex GUI (basically a table with dynamic rows and columns as well as categories and subcategories); since I couldn't think of a standard xaml-way to achieve that, I'm writing a custom control that is supposed to display my data.
So long story short, I'm creating a lot of different WPF UI elements in C# code directly, not in XAML. Now I'll need a way to synchronize some of these component's values with dynamically changing data. An obvious example is that some of my text boxes (or labels or whatever) will need to display the price of a stock. It should thus be bound to another class which provides up to date prices.
My main problem is that I don't know in advance which prices will be needed and where they should be displayed. So what I'd need is basically a way for my textbox to contact my price-object and ask "hey, i'm going to need a price for stock US0123456789. Please tell me that price and keep updating my value whenever the price of that stock is updated."
All databinding examples I found were usually focused on binding to the variables within a specific object instance, but I can't simply bind to, say, PriceObject.Price because there can't be a simple "Price" variable. After all, there's going to be various different stocks managed by the price object and each text box only needs the price of one specific stock, so it'd need to bind to something like PriceObject.PriceForStock("US0123456789"). I couldn't find a way to bind to a method, though, and I don't know how how else it'd be possible.
The only way I could think of was to have a Dictionary in my GUI-class witch stock ISINs as its keys and a reference to the UI Element as value. Then my GUI could observe the Price Object and each time prices change, and event is triggered and the GUI class could update the UI Element manually, something like (pseudo code incoming):
private Dictionary<string, UIElement> displayed_stocks = new Dictionary<string, UIElement>();
private void create_gui()
{
Textbox textbox = new Textbox();
displayed_stocks.Add(isin, textbox);
}
private void receive_change_event_of_price_object(string affected_isin, double new_price)
{
displayed_stocks[affected_isin].Text = new_price.ToString();
}
But I don't know, I feel like this is a sloppy solution. Especially because I won't only need dynamic prices but also other dynamic information like portfolio holdings, which will rely not only on ISIN but on ISIN and portfolio ID, so it wouldn't be that simple with a dictionary. Is there any better way to do it? I'd be glad to be pushed in the right direction there!
Thanks
If you create an indexer on the object you bind to you can bind with a parameter in a clean and easy manner, see this link for more information.
Dynamic Bindings are achieved using...
Indexer as Bas has already said above. Even ToString() can do the trick too.
MultiBinding with IMultiValueConverter deciding which binding source(s) should take effect. MultiBinding has an advatnage that you can bind all possible things that can be displayed in your TextBox and send them to the converter (whether available or not) and then the converter will decide which one to mould and display.
If the sequence of priority of source values is fixed then you can use PriorityBinding. No need for the converter discussed above.
I'm working on a project that controls multiple devices over USB and intercepts the WM_DEVICECHANGE events from Windows to manage currently connected devices and plugin modules using those devices. There exists a combobox on the main form that (should) display all available devices (the custom object) and be dynamically updated in the event of either device arrival or removal.
Now, every tutorial that I have read including some from here have directed me to set the DataSource property of the combobox to the List of objects that I have, and leave the DisplayMember/ValueMember property blank to display ToString() and to return the object as the value.
In some instances I have tried (such as post instantiating the List and populating it with sample/real objects) the combobox populates, however upon removal or arrival, the collection in the combobox does not update even when reassigning the List to the combobox's DataSource property after every device arrival/removal method.
EDIT: Oh right... the question...
How do I databind the collection of (custom objects returned as the values) dynamically such that it can handle sudden changes (additions/removals) to the list's contents?
EDIT 2: Sorry I didn't make this more clear, wasn't aware of how pervasive WPF has gotten, but this is a WinForms project.
Thanks in advance for any help you can provide. :)
even when reassigning the List to the
combobox's DataSource property after
every device arrival/removal method.
After reassigning, you need to call .DataBind() again.
If you're using .net 3.5 or above, you can use an ObservableCollection to have the list update automagically.
I'm not sure if you're using WinForms or WPF. I'm assuming WPF as nobody should start out on WinForms nowadays...
You need to change your List to an ObservableCollection<T>.
The WPF binding model relies heavily on a magic subsystem of fairies and warlocks (not mocking you, I'm actually serious). They have their own language for informing each other that something has changed between the DataContext and UI. These are primarily the DependencyObject/Dependency properties, INotifyPropertyChanged and INotifyCollectionChanged, and the ObservableCollection<T>.
By proper use of these totems, changes in your ViewModels/Models (the stuff you stick in the DataContext and/or bind to the DataSource) will be reflected on the UI.
I don't know about that ToString() bit. I always set the DisplayMember to the Property I want to display. I don't care about the ValueMember because the SelectedItem is my Object.
DataBind doesn't apply if this is a WinForms project, which it sounds like. (USB and stuff)
I don't do anything funky in my project when up update the data in a ComboBox, I just set the DataSource again.
EDIT:
You could try using a BindingList rather than a List also.
http://msdn.microsoft.com/en-us/library/ms132679.aspx
I used an application recently that was awe-inspiring. All the forms inherited from their own classes and a 'form' came with an amazing amount of functionality and looked the nuts.
What I'm interested in is this 'feature' of the form. This was a C# WinForms project and blew me away.
The forms were bound to objects that the group had written to support two-way data binding (to an extent). The way they behaved was pretty simple:
The data input forms all had controls that inherited from textbox and these were bound to properties of an object, Entering data immediately validated it and the box was a light pink if validation failed and a light green if it passed. If the box ever turns blue this actually means the value in the database the form is bound to has changed and your changes to the controls were immediately saved when valid values entered. It was the case that sometimes a section of controls had to be filled before a save occured. But it was all automatic. You could stop at any point and come back later and continue without actually saving yourself.
And like I say if someone else is editing the same record values they change caused your textboxes to become blue and you knew you needed to reload the screen to see up to date information.
All of this came from using their own form class they had written and their own textbox controls bound to an objects property.
I'm mainly wondering how the hell did the object figure out the value had been changed by someone else. It surely isn't polling the database. This system was amazing. The brilliance didn't stop there.
For simplicity. How might I create an object or collection of objects to mimic the bahaviour. I'm not going to but I can't even see how.
Thanks
I'm pretty sure that anything involving other people's changes would have needed to hit the database. For two-way binding, all you really need is change notification - i.e. INotifyPropertyChanged (or a FooChanged event for every Foo property). This is all abstracted into TypeDescriptor - i.e. any binding that uses the regular PropertyDescriptor implementation (which it should) will know about notifications via SupportsChangeEvents, AddValueChanged and RemoveValueChanged.
For validation - IDataErrorInfo is your friend; by implementing this, you can volunteer validation information (which is used and displayed by several controls, such as DataGridView). i.e.
IDataErrorInfo dei = obj as IDataErrorInfo;
if(dei != null) { // supports validation
string err = dei["PropName"]; // or .Error for overall status
bool clean = string.IsNullOrEmpty(err);
}
Note that an alternative approach would be to have a Color property on the data aobject, and bind that directly to the textbox etc.