Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# WPF MVVM DataBinding , +
Hi,
 
i am writing a wpf applivation with the mvvm pattern. in my viewmodel, i receive the data asynchron over a wcf service:
#region Construction
public  AddressViewModel()
{
    this.LoadAddress();
}
 
private async void LoadAddress()
{
    ServiceClient client = new ServiceClient();
    _address = await client.GetAddressByIdAsync(1);
}
#endregion
I bind the propertys in view like this:
<TextBlock Grid.Column="1" Grid.Row="0"  Text="{Binding address1, IsAsync=True}"/>
The UI doesnt update automatically after the asynchron load. When i change a property via button (for example) the UI updates, so the problem must rely on the asynchron WCF-Call. I tried the following changes and they do the job but i think this is not good practice.
private async void LoadAddress()
{
   ServiceClient client = new ServiceClient();
   _address = await client.GetAddressByIdAsync(1);
   RaisePropertyChanged("address1"); //Do this for each property?
}
Do i really have to RaisePropertyChange("propName") for each property of my class or is there a better, cleaner, more elegant way?
 
EDIT:
Normaly i raise the propertychangeevent in the setter like this:
public string address1
{
   get { return Address.address1; }
   set
   {
       if (Address.address1 != value)
       {
           Address.address1 = value;
           RaisePropertyChanged("address1");
       }
   }
}
Posted 28-Dec-12 9:22am
Edited 28-Dec-12 10:19am
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Unfortunately yes. If you do not use something like Notify Property Weaver[^] you will need to raise the notify on each property change.
 
If you do not go down the automated route, I would really recommend setting your property value and then raising the changed event on the property setter rather than the method / void call your are doing. This helps keep code maintainable and in one place. Only my opinion but having raise property events in method calls can get messy unless really needed.
  Permalink  
Comments
ChrisTopherus at 28-Dec-12 15:16pm
   
Hi db7uk,
i will have a look at the NotifyPropertyWeaver. For the second part of your solution:
 
that is the part i do not understand. i raise the propertychangedevent in the setter of the property. please look at my edit on the question. maybe there is an other problem... ???
db7uk at 28-Dec-12 15:40pm
   
You will need to raise the property changed event. This must be done in order for the UI to know a change has happened. Without it how would the UI know when to update itself? So you setter is correct. Interesting though, what is Address.address1? is this a model property within the viewmodel? So back to the question. You do need to raise the property changed event when something in your viewmodel property changes.
db7uk at 28-Dec-12 15:43pm
   
Added to that, consider using reflection property names. i.e. RaisePropertyChanged(() => address1). By strongly typing your property changed event will allow compile time support if your property name changes. Consider looking at Prism for Notifiable objects and delegate commands.
ChrisTopherus at 28-Dec-12 16:13pm
   
All servicefunctions/sql-statements etc. i use are "autogenerated" from a datacontract on the serverside. and the class Address has address1, address2, address3 to hold street and additional stuff... i know that this is not looking good^^
RaisePropertyChange(()=>address1) also works. The strange thing for me is, that the set of the propertys isn't called, when i update the whole object. with your info on your solution, i will call the raiseprop for all properties in the setter of the object:
 
#region Properties
public Address Address
{
get
{
return _address;
}
set
{
if(Address != value)
{
_address = value;
if(address1 != value.address1)
RaisePropertyChanged(() => address1);
if(address2 != value.address2)
RaisePropertyChanged(() => address2);
...
}
}
}
so i dont have it in method. do you think this is a good solution?
db7uk at 28-Dec-12 16:50pm
   
This is the better approach. I would host the Address class as a property and bind to that. i.e. text="{Binding Address.address1, IsAsync=True}" You would then only need to raise the changed event once. .i.e.
public Address Address
{
get
{
return _address;
}
set
{
if(Address != value)
{
_address = value;
RaisePropertyChanged(() => Address);
}
}
}
ChrisTopherus at 28-Dec-12 17:48pm
   
And exactly this is the confusing point. I thought the UI will update (adress1, address2, etc) when i raisepropertychanged on the whole Address but it wont...
db7uk at 28-Dec-12 18:22pm
   
mmmmmm, so your WCF call returns an addresses object? This addresses object has address1, address2 etc properties? You are binding directly to the addresses.address1 property? this should work. What happens if you make the call in an synchronous way?......... Out of interest, are you binding to address1, address2 properties in your viewmodel or to the properties in the addresses class?
ChrisTopherus at 28-Dec-12 18:35pm
   
first of all: THANK YOU FOR YOUR HELP :)
 
yes, my wcf call returns an address with the property address1, address2 etc.
 
i bind to the propertys of the viewmodel. i set the datacontext of my view with:
 
usercontrol.datacontext>
addressviewmodel/>
/usercontrol.datacontext>
 

when i call synchronus, then it works. i dont even have to call the raisepropertychange in the setter of the Address as discussed above.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

EDIT:
Sometimes you think to yourself... DOOOH Smile | :)
If someone is looking for this too:
http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.propertychanged.aspx[^]
 
If you update your hole object, just do
RaisePropertyChanged(null);
and you'll get all propertys updated.
 
Thx to db7uk for support.
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 Maciej Los 295
1 OriginalGriff 273
2 Aajmot Sk 234
3 Marcin Kozub 205
4 Richard MacCutchan 200
0 OriginalGriff 7,903
1 Sergey Alexandrovich Kryukov 7,127
2 DamithSL 5,604
3 Manas Bhardwaj 4,986
4 Maciej Los 4,820


Advertise | Privacy | Mobile
Web02 | 2.8.1411023.1 | Last Updated 29 Dec 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100