Bind to Object Itself, Not One of It's Properties - asp.net

Using Asp.net's Bind() method, how do I bind to the object itself, not one of it's properties?

I think what Ryan means here like if you have to an object like this
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
And if you bind Person object to anywhere in GridView or Repeater to any DataSource you only bind Person and it get a default bind value from one of its properties.
support we have a variable Ryan from Person type so i want to get the variable value from calling <%# Eval("Ryan") %> not <%# Eval("Ryan.FirstName") %>
I tried to put an attribute DefaultBindingProperty for the class but it's not working
[System.ComponentModel.DefaultBindingProperty("FirstName")]
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
So does any one knows how to do it properly?

I ended up working around this by adding a property called SelfReference that simply returns this. If anyone reads this and has a better solution, I'd like to hear it.

You may use Container.DataItem instead:
Item='<%# Container.DataItem %>'

I'm not sure to what exactly you want to bind. The only thing that would make sense to me at the moment is to bind to some UI control, say a DropDown control for instance.
There usually some text properties for the value being displayed and value properties for the actual value to function as identifier. On the Dropdown
DataTextField
DataValueField
There you specify DataTextField = "Firstname" and DataValueField = "Id" given that you have an object that has properties "Firstname" and "Id".
On lists you can use the Eval function directly on your ASPX code or you add server-side controls (i.e. Literals, Labels) inside the list templates and implement the ItemDataBound event (taking the Repeater as example). Here's a good example which illustrates this further.
Hope I was able to help a little ;)

I figured out a way somehow. Actually it is in "http://msdn.microsoft.com/en-us/library/ms752347.aspx"
ListBox ItemsSource="{**Binding**}" IsSynchronizedWithCurrentItem="true"/>
Note that although we have emphasized that the Path to the value to use is one of the four necessary components of a binding, in the scenarios which you want to bind to an entire object, the value to use would be the same as the binding source object. In those cases, it is applicable to not specify a Path. Consider the following example:
XAML
Copy

Related

Difference between DropDownlist or DropDownListFor Html helper

It seems weird that I couldn't find an explanation of the difference between those two helpers, so I would assume that is something obvious but I missed.
Basically I am trying to decide which one I should use for my case, with the following simple Model:
public class Booking
{
public int ID { get; set; }
public Room Room { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public ICollection<Equipment> Equipments { get; set; }
public string Who { get; set; }
}
and I want display a simple Room DropDownlist for Adding and Editing Booking record.
After doing a lots of Google around, it seems that I probably need a DropDopwListFor, but not sure why and how?
Take the following two examples:
#Html.DropDownListFor(
x => x.EquipmentId,
new SelectList(Model.Equipments, "Id", "Text")
)
and:
#Html.DropDownList(
"EquipmentId",
new SelectList(Model.Equipments, "Id", "Text")
)
It is obvious that with the second example the name of the property you are binding the dropdown to is hardcoded as a magic string. This means that if you decide to refactor your model and rename this property Tooling support that you might be using has no way of detecting this change and automatically modifying the magic string you hardcoded in potentially many views. So you will have to manually search & replace everywhere this weakly typed helper is used.
With the first example on the other hand we are using a strongly typed lambda expression tied to the given model property so tools are able to automatically rename it everywhere it is used if you decide to refactor your code. Also if you decide to precompile your views you will get a compiler time error immediately pointing to the view that needs to be fixed. With the second example you (ideally) or users of your site (worst case scenario) will get a runtime error when they visit this particular view.
Strongly typed helpers were first introduced in ASP.NET MVC 2 and the last time I used a weakly typed helper was in an ASP.NET MVC 1 application long time ago.
DropDownListFor will automatically select the selected value by using the specified property:
// Will select the item in model.Equipments that matches Model.EquipmentId
#Html.DropdownListFor(m => m.EquipmentId, Model.Equipments);
Another comment:
Don't have ICollection<Equipment> Equipments in your view model. You should have a property that returns an IEnumerable<SelectListItem>.
When you want to add a view (aspx file) where this DropDownList or DropDownListFor will be inside, rightclick->add view then select "Create a strongly typed view" then in list select Booking class. After that add this page.
You can write in it as follows:
#Html.DropdownListFor(m => m.Equipments , Model.Equipments);
because we add strongly typed view as Booking, you can have:
m => m.ID, m => m.Room, m => m.StartTime
... etc.
In your services you can have methods to take data from database, then use this service's method in your controller to pass data from database to view. You can use ViewData in your controller:
ViewData["Equipments"] = new servicename().getdatalistfromdatabase().AsEnumarable();
Putting AsEnumarable() at the end of your list taken from database makes it IEnumarable.
Then in your view, you can also have :
#Html.DropdownList("MyEquipments" , ViewData["Equipments"]);
A link on ViewData usage:
http://msdn.microsoft.com/en-us/library/dd410596.aspx
I hope that helps you.
DropdownListFor is support strongly type and it name assign by lambda Expression so it shows compile time error if have any error.
DropdownList not support this.

StackPanel has a DataContext, how to populate ListPicker with option values from another?

I'm new to WP7 development, so binding is still a little foreign to me. I have a StackPanel that I've set the DataContext with TwoWay binding for editing a given record. But, within the "form" I have a ListPicker that I want to populate with possible values from a lookup table.
Currently I've created a DataTemplate and set the ItemsSource property of the ListPicker. Since the sole TextBlock in the DataTemplate is binding to the ItemsSource data context, how do I then bind the ListPicker's SelectedItem to the StackPanel's data context?
Your object that you assign to StackPanel's DataContext must expose appropriate properties, for example:
class MyData
{
public Data { get; set; }
public Selected { get; set; }
}
Then you need to bind ListPicker's ItemsSource: ItemsSource={Binding Data} and ListPicker's SelectedItem: SelectedItem={Binding Selected}.
If you want ListPicker to react when you change MyData's Selected property you will need MyData class to implement interface IObservable. The same goes for Data property, this collection must inform when it's state changes, so make it of type: ObservableCollection<ElemType>.
Check this: Using the parent's DataContext (WPF - Dynamic Menu Command Binding)
Check all answers and see if one of them helps you.

DataKeyNames in databound controls must be a property?

I use a ListView along with an ObjectDataSource tied to a business object. This object is defined as follows:
public class Employee
{
public int Id;
public string Name;
}
When I try setting the DataKeyNames property of the ListView to Id, ASP.net blows up and says:
DataBinding: 'Employee' does not contain a property with the name 'Id'.
However, when I change the object to that:
public class Employee
{
public int Id {get; set;}
public string Name;
}
It works!!!
I couldn't find any documentation about this behavior. Why is it not accepting a simple variable for DataKeyNames and instead it insists on a property?
There's not really a long explanation for this one, you've already found it. ASP.Net can bind to properties and not public variables. This is probably tied to the way the MSIL is generated. When compiled, a property is generated as a method (and binding allows you to bind to methods and properties) while public variables are not.
Unfortunately a quick search didn't uncover the reasoning beyond my own guess above, but here is MS saying "properties, expressions, methods" also: http://support.microsoft.com/kb/307860

ListBox doesn't show changes to DataSource

I thought this was a simple problem, but I can't find any information on the web. I'm binding a ListBox to a List using BindingSource like so:
List<Customer> customers = MyMethodReturningList();
BindingSource customersBindingSource = new BindingSource();
customersBindingSource.DataSource = customers;
customersListBox.DataSource = customersBindingSource;
Now, when I add or delete from customers list, my ListBox gets updated (even without using ResetBindings on BindingSource), but if I change any of the customer objects in the list, it does not. Calling ResetBindings has no effect. I even implemented my own BindingList, but the behaviour hasn't changed.
The Customer class uses properties for accessing and modification of data. Its ToString() content is displayed in the list.
I'm using C# in .Net 2.0.
Any ideas?
Thanks
If you use a BindingList you don't even need the BindingSource:
BindingList<Customer> customers = new BindingList<Customer>(MyMethodReturningList());
customersListBox.DataSource = customers;
OK, here's a dirty fix: wenever you need to refresh the box contents set datasource = null, then rebind it.
the reason it doesn't update is because the objects in the list haven't changed and it only checks the refrences of the object rather than their contents.
There is also a bug in the list box which can cause this problem. If you set the SelectionMode to None this problem appears.
As a work around I set the selection mode to One and then back to None when updating the datasource.
I got around this problem by converting data to array when updating source. Please see UpdateData method. This way you can update your combo box without losing ComboBox Settings.
class Person {
public int Id {get; set; }
public string FirstName{ get; set; }
public string SurName {get; set; }
}
public Form1()
{
InitializeComponent();
comboBox1.DisplayMember = "FirstName";
comboBox1.ValueMember = "Id";
comboBox1.DataSource = m_PersonList;
}
public void UpdateData() {
m_PersonList[0].FirstName = "Firstname1";
comboBox1.DataSource = m_PersonList.ToArray<Person>();
}
I understand that this question was asked almost 6 years ago but other than work-arounds I do not see a correct answer here.
When you change property of an item in a collection the event gets raised for the element (object) but not the collection. So the collection does not see a change and will not refresh bound controls. Elements inside all binding collections and most generic collections like List<> receive 2 events, PropertyChanging and PropertyChanged. When a property of the element inside collection is changed, the event gets triggered. All you need to do is add an event handler that would trigger either re-binding or raise an event on the Collection.

Confused about databinding in ASP.NET

Lets say I have an object
class Person {
public string Name { get; set; }
public int Age { get; set; }
}
And that object is retrieved from a Factory (ie Can't use SQLDataSource or anything like that)
Person person = PersonFactory.GetPerson();
How can I two-way DataBind the two properties to Textboxes on a web form? I looked into FormView, but that doesn't seem to fit my needs as I am not iterating over a collection of objects. And when I tried to use it, I don't seem to be getting the posted values in the Person object in the FormUpdated event. And I am binding like this
Markup
<asp:Textbox Text=<%# Bind("Name") %> />
Code behind
FormView1.DataSource = new List() { person };
FormView1.DataBind();
I feel like I am missing something really obvious. Should I be using a FormView? It doesn't seem like it a proper fit for simple data binding, but the <#% Bind %> method must be in some type of container -- is there a more suitable object?
You need to handle the updates to your FormView - the updates in the asp.net databound controls are not automatic. I'd also consider using an ObjectDataSource - keeping your binding all in the markup can make things easier to find. When you use the ObjectDataSource - it'll automatically wrap your single object in an IEnumerable, so binding to a method that returns a Person is acceptable. You could also consider using a DetailsView if you don't want to write out the form yoruself. In your case, you could do the following
<asp:FormView runat="server" DataSourceID="MyPersonDataSource"> ... </asp:FormView>
<asp:ObjectDataSource runat="server" ID="MyPersonDataSource"
TypeName="PersonFactory" DataObjectTypeName="Person"
SelectMethod="GetPerson" UpdateMethod="UpdatePerson" />
And to facilitate this, you'd need an UpdateMethod(Person) method on your PersonFactory class. Doing it this way eliminates your binding from the codebehind, and will allow your updates to your person object to be persisted to your data store without you having to handle the update events yourself.
Try calling the DataBind method on your TextBox controls.
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
MyTextBox1.DataBind();
MyTextBox2.DataBind();
}
I've never tried doing two way binding in exactly this way before, but using the Bind("property") syntax, it should work this way as far as I know.
If calling the DataBind method doesn't work, then the FormView is your best bet.
DataBinder.Eval(Container.DataItem, "Name")
This should do the trick, but I think you need some event-handling of your own to do the 2-way binding.

Resources