Usually, when I code property of classes that could be edited by the user with a binding of some kind... To prevent executing of GUI logic, I don't allow to assign the same value to the property:
public PMSAccountingYear AccountingYear{
get { return _accountingYear; }
set{
if(_accountingYear == value)
return;
_accountingYear = value;
NotifyOtherProperties();
LogChanges();
EmallToTheBoss();
Errr();
BlowBombInTheGarden();
Etc();
}
}
The condition check doesn't look elegantly, and cannot be detected with any automatic code analysis.
Can you please suggest a better case?
With one of the attributes maybe?
What you are doing is perfectly fine; this is the common way to implement setters for things like INotifyPropertyChanged (aee also the example on that page).
As the value did not change, there is no need to actually update the backing field and especially not to notify others of a “changed” value.
Related
I'm not sure why I should use RaisePropertyChanging, when notifying the view fx:
private LoggingLvl _myLoggingLvl;
public LoggingLvl MyLoggingLvl
{
get { return _myLoggingLvl; }
set
{
RaisePropertyChanging("MyLoggingLvl");
_myLoggingLvl = value;
RaisePropertyChanged("MyLoggingLvl");
}
}
why is it recommended to use RaisePropertyChanging?
Using INotifyPropertyChanging would allow consuming code a chance to consume the previous value of a property, before a change is applied. This is not frequently going to be useful, but there are cases where it might be: if you imagine a property that represents an "active object," this event would allow you to trigger code that would fire when the object is de-activated.
As a contrived example, consider a UI where the change in value of a field is required to display in a specific way: the old value should "float" off the screen leaving the new value behind. If a model class implemented INotifyPropertyChanging, a viewmodel class could attach to this event in order to cache the old value for use in the float animation. This allows the model class to represent the current state, while the viewmodel can maintain all values necessary to drive the UI.
I have never listened before that RaisePropertyChanging is recommended. You can use it if you need to notify to "outside world" that specified property is going to changed.
This can be useful, for example, when some parts of your application should validate the changing property state against other parameters of your system, so may be also signal that it's not a subject to change, as following Single Responsibility Principle your class may not be aware of states of other instances of types of your application.
The INotifyPropertyChanging interface is used to notify clients, typically binding clients, that a property value is changing.
http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanging.aspx
assume for a long running validation task on your property. hope take 5 seconds for updating the property value. meanwhile some other property are are looking for it these properties are treated under race condition. and wait under a queue and one property changed notification done then the first object will get change to get or set the property value.
let me give you some examples.
I am working with WPF and MVVM, and so have a lot of properties in my view models that are bound to stuff in the view. The majority of these properties look like this...
private DateTime _newRevisionDate = DateTime.Now;
public DateTime NewRevisionDate {
get {
return _newRevisionDate;
}
set {
if (_newRevisionDate != value) {
_newRevisionDate = value;
RaisePropertyChanged(ViewModelUtils.GetPropertyName(() => NewRevisionDate));
}
}
}
I'm using MvvmLight, which is where the RaisePropertyChanged() method comes from, and have used the ViewModelUtils.GetPropertyName() method to create a string from the property name, avoiding the need for magic strings.
Now, the problem is that if I add a few such properties to a view model, I end up with a large amount of almost identical code. This just cries out for some clever refactoring, so I can just use a single line of code to define each property.
However, I haven't been able to find any way to do this yet. What would be nice is to be able to do something like the standard C# automatic properties...
public DateTime NewRevisionDate { get; set; }
...but have it call RaisePropertyChanged() whenever the property is set to a new value.
Anyone any ideas? Thanks
This just cries out for some clever refactoring, so I can just use a single line of code to define each property.
Well you can make it a single line now. It's just a very long line :)
C# 5 makes this slightly easier with caller info attributes, so you don't need the GetPropertyName part - and that's the ugliest part of your current code.
The other thing you could do would be:
set
{
_newRevisionDate = PossiblyFireEvent(RaisePropertyChanged, _newRevisionDate, value);
}
where PossiblyFireEvent would take the property name as an optional parameter using the caller info attributes, RaisePropertyChanged as a delegate to execute if the two values were unequal, and always return value. Not sure it's worth it though.
as I often let LinqToSql generate partial entity classes, I am wondering if my practice of adding additional properties via code is correct and if there is a better way of doing the same thing? I am also wondering what is the difference between accessing the values of other properties using this.PROPERTY_NAME vs _PROPERTY_NAME?
In my web app I keep using this.PROPERTY_NAME, but I am wondering if that is, as I already said in opening sentence, the proper approach I should be using. Also, What is _PROPERTY_NAME and when do we use it?
Example:
public partial class User
{
public bool IsThisProper {
get{
return this.SomeIntProperty == 10; // I usually use this
}
}
public bool WhenToUseThisApproach {
get{
return _SomeIntProperty == 10; // What is this in comparison to above?
}
}
}
One is the property, and the other is the private backing field in which that property stores it's value. If you want to execute whatever code the property has in it's getter/setter, then use the property, if you don't, then don't. Chances are you want to use the property, not the field, especially with setting (setting it triggers the property changed event, so about the only time to use the property is if you don't want that event raised).
Looking for guidance on where to place code which is dependent upon changes to a property.
For example, I have a view model which is used to hold state for an applications settings
public SettingsViewModel(ISettingsRepository settings)
{
_settings = settings;
// ...
}
For each change to a settings property we have to persist this change to the repository, and on some properties, other properties are affected, so additional code is required.
I started off just adding this logic to the setter
public ProjectCollection Projects
{
get { return _projects; }
set
{
if (_projects == value) return;
_projects = value;
RaisePropertyChanged("Projects");
// Extra work needed when collection of projects change
_settings.SaveProjects(_projects);
Startable = _projects != null && _projects.Count > 0;
}
}
But then swapped over to wiring up the PropertyChanged event for INotifyPropertyChanged and removed the additional code out of the property setter
public SettingsViewModel(ISettingsRepository settings)
{
_settings = settings;
// ...
PropertyChanged += onPropertyChanged;
}
void onPropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "Projects":
_settings.SaveProjects(Projects);
Startable = Projects != null && Projects.Count > 0;
break;
// ...
}
}
public ProjectCollection Projects
{
get { return _projects; }
set
{
if (_projects == value) return;
_projects = value;
RaisePropertyChanged("Projects");
}
}
Having the logic inside the setter means less code to write, less chance of making a mistake wiring up the wrong property name (unit test should pick this up though) and would be slightly faster, although probably insignificant.
Having the logic wired up to an event seems to be a more maintainable approach, so long as the methods are appropriately named it should be easier to follow the code, and means the setter isn't doing other work besides setting the property. I'm guessing it might also provide more flexibility, using the example above, if the requirements changed so that persisting of changes happened from another event e.g. "Save" button click instead property change, then the code should be easier to change.
I appreciate this is a subjective question, but I'm new to the MVVM pattern (although I guess it may hold true for any setter logic?) so am looking for other reasons before I settle on an approach. Thanks!
When deciding what code to put where, remember this: a ViewModel is for presenting the data to the View. It can massage or manipulate the data a little to do so (within reason of course - changing a value to a color could be considered absolutely fine to do). The ViewModel doesn't know anything about the UI, and it doesn't know anything about saving data.
The property setters should be kept as simple as possible, and they should notify if anything relies on them (which mostly will be the case - the VM is used for binding). This means that your second example utilizing the OnPropertyChanged() event handler is a far better option than the first example.
However, it still knows too much for my liking. I would raise events which the Model can subscribe to, and let the Model do the work. The ViewModel should just say "hey, my data has changed, I don't care what you do about it but i've told you so do whatever you like". The Model can then either save instantly, or what till more changes have taken place before persisting the data.
thanks for your attention and time.
I want to implement validations in settter of properties. Here is an issue where your expert help is required please.
I have idea of how I will do validations before setting value. but not getting what to do if passed value is not correct. Just not setting is not a acceptable solution as I want to return an appropriate message to user (in a label in web form). My example code is:
private int id;
public int Id
{
get
{ return id; }
set
{
bool result = IsNumber(value);
if (result==false)
{
// What to do if passed data is not valid ? how to give a appropriate message to user that what is wrong ?
}
id = value;
}
}
A thought was to use return but it is not allowed.
Throwing error looks not good as generally we avoid thorwing custom errors.
Please guide and help me.
thanks in anticipation
haansi
You could consider throwing appropriate exception from property setter. That way it will be clear to the calling party what went wrong, especially assuming you have business rules with respect to setting properties. Of course you do expect the caller to do validations, if still there is a problem, then throwing exception doesn't seem that bad.
"It is valid and acceptable to throw exceptions from a property setter."
Property design guidelines
Best practices: throwing exceptions from properties
What exception to throw from a property setter?
I think you'd better change to another example because:
public int Id
{
get { ... }
set
{
if (!IsNumer(value)) // changes to if (value>5)
{
//the code here will never be executed
id = value;
}
}
}
If the check is only about number (type) then your property can very well handle the type safety. Eg. User wont be able to assign string to a property accepting int.
I would suggest that if Property involves certaing computations, then one should consider using a method instead. In that case, you will option to get some text in return.
One more option is to store all these validation checks in an instance collection (inside the same object). Like.
private List _faileValdations;
//more code
set
{
if (!IsNumber(value))
{
_faileValdations.Add("Invalid value for xxx. Expected... got..");
}
else{
id = value;
}
}
And then, your GUI can read the FailedValidations collection in the end, and display it in a formatted way in some label.
Edit: one more option below.
Sorry i forgot to mention about this before.
You can use an event driven approach also.
You object can expose an event like "ValidationFailed", and all the GUI objects can subscribe to this event. The object will trigger this event in case any validation is failed in the setters.
set {
if (!IsNumber(value))
{
RaiseValidationFailed("some message");
}
else{
id = value;
}
}
"RaiseValidationFailed" can collect the message, wrap it up in some event args and trigger "ValidationFailed" event with the message. Then GUI can react to this.
{I can provide you a full code for this if its not clear}
I would argue that you should rethink your approach to validation. The approach that you are suggesting means that every time a property changes, a message will be generated.
How will these messages be collected, stored and presented? Especially if you decide to use your classes in a website?
What if you want to validate your class at any other time?
What if you want to use the same rules in client side validation?
I can understand the appeal of catching an invalid value as early as possible, but it is a lot easier to validate an entire class in one call such as a Validate() method. This way, you have full control over when the validation logic is run.
I would recommend you read up on the two leading approaches to property validation:
Data Anotations
Fluent Validation for >NET 3.0 and above
Fluent Validation for .NET 2.0
Both Data Annotations and FluentValidation are easy to use and they are able to generate well-tested client side validation on web forms and win forms.
In Data Annotations, the validation is added to the properties using attributes. If you prefer to keep your data classes as clean data transfer objects, Fluent validation involves the creation of easily readable rules in Validator classes.