Lets say there is a Person class that holds some attributes and some other classes Address etc. (I am just giving an example of class{class{data}})
An instance of this is deserialized and loaded in the ui. The used might change the data (the name, the address or something).
If the instance is the datasource in the ui(in every control), how can I know if the data has been changed in order to notify the user to Save before exit?
You should implement the INotifyPropertyChanged interface, which basically exposes an event that Person should raise when a property changes.
The linked documentation gives an example with a DemoCustomer class which is likely to translate pretty easily into your Person class.
To avoid anoying code for every property of every class you did and will do, you can use one of AOP frameworks. This one is one of the best actually available on market now: PostSharp. And there is also a free version, which is a good news. (by the way keep an eye on licensing, in case you're gonna use it at your work)
Here you can actually find an example how to use precisely for injecting of NotifyPropertyChanged
http://www.sharpcrafters.com/solutions#ui
Hope this helps..
Related
I am trying to make a 2-way binding of a class property.
public class MyClass{
public MyField AField1{get;set;};
public MyField AField2{get;set;};
}
public class MyField{
public string Value {get; set}
}
MyClass _class = MyClass();
_dv.DataSource = _class;
Databinding text object displays MyField class name instead of Value Property. I also tried to enter:
DataMember = "AField1.Value";
Is there any way to bind (2-way) AField1.Value of a class MyClass to a visual control?
It's a pain. There's no built-in way to achieve this in .NET, so I can safely say, even less in the CF.
You can get started with this article on MSDN Blogs, but it's pretty limited as you can only get one level of nested property bindings.
Personnally, I ended up writing a custom BindingSource, based on code that lies somewhere on the internets. I can't give you source code of my rewrite as it's property of my employer, but here's the link to the project that got me started.
There are a few drawbacks to the code provided : some of his namespaces are System.ComponentModel, and VS2010 didn't seem to like, so I had to rename them. And a few more issues in design time that can make it a pain to use (so you'll want to fix that too), like loosing the list of properties when you make a spelling mistake and so on...
But it's the best shot (IMHO) at creating a good BindingSource that handles nested objects, and you'll get the idea of what needs to be done to achieve your nested bindings.
The last drawback (and biggest probably, but I have no experience with CF) is that the project is written for the regular .NET Framework, so it's likely that you will have to rewrite it entirely.
Hope that helps....
Edit. Uh oh, I've been grave-digging without noticing... sorry.
PS. Another idea is to simply create one binding source for each of your nested objects, but it gets messy (IMO) if your object hierarchy is complex.
First off, I have read through a list of postings on this topic and I don't feel I have grasped properties because of what I had come to understand about encapsulation and field modifiers (private, public..ect).
One of the main aspects of C# that I have come to learn is the importance of data protection within your code by the use of encapsulation. I 'thought' I understood that to be because of the ability of the use of the modifiers (private, public, internal, protected). However, after learning about properties I am sort of torn in understanding not only properties uses, but the overall importance/ability of data protection (what I understood as encapsulation) within C#.
To be more specific, everything I have read when I got to properties in C# is that you should try to use them in place of fields when you can because of:
1) they allow you to change the data type when you can't when directly accessing the field directly.
2) they add a level of protection to data access
However, from what I 'thought' I had come to know about the use of field modifiers did #2, it seemed to me that properties just generated additional code unless you had some reason to change the type (#1) - because you are (more or less) creating hidden methods to access fields as opposed to directly.
Then there is the whole modifiers being able to be added to Properties which further complicates my understanding for the need of properties to access data.
I have read a number of chapters from different writers on "properties" and none have really explained a good understanding of properties vs. fields vs. encapsulation (and good programming methods).
Can someone explain:
1) why I would want to use properties instead of fields (especially when it appears I am just adding additional code
2) any tips on recognizing the use of properties and not seeing them as simply methods (with the exception of the get;set being apparent) when tracing other peoples code?
3) Any general rules of thumb when it comes to good programming methods in relation to when to use what?
Thanks and sorry for the long post - I didn't want to just ask a question that has been asked 100x without explaining why I am asking it again.
1) why I would want to use properties
instead of fields (especially when it
appears I am just adding additional
code
You should always use properties where possible. They abstract direct access to the field (which is created for you if you don't create one). Even if the property does nothing other than setting a value, it can protect you later on. Changing a field to a property later is a breaking change, so if you have a public field and want to change it to a public property, you have to recompile all code which originally accessed that field.
2) any tips on recognizing the use of
properties and not seeing them as
simply methods (with the exception of
the get;set being apparent) when
tracing other peoples code?
I'm not totally certain what you are asking, but when tracing over someone else's code, you should always assume that the property is doing something other than just getting and setting a value. Although it's accepted practice to not put large amounts of code in getters and setter, you can't just assume that since it's a property it will behave quickly.
3) Any general rules of thumb when it
comes to good programming methods in
relation to when to use what?
I always use properties to get and set methods where possible. That way I can add code later if I need to check that the value is within certain bounds, not null etc. Without using properties, I have to go back and put those checks in every place I directly accessed the field.
One of the nice things about Properties is that the getter and the setter can have different levels of access. Consider this:
public class MyClass {
public string MyString { get; private set; }
//...other code
}
This property can only be changed from within, say in a constructor. Have a read up on Dependency Injection. Constructor injection and Property injection both deal with setting properties from some form of external configuration. There are many frameworks out there. If you delve into some of these you will get a good feel for properties and their use. Dependency injection will also help you with your 3rd question about good practice.
When looking at other people's code, you can tell whether something is a method or a property because their icons are different. Also, in Intellisence, the first part of a property's summary is the word Property.
You should not worry about the extra code needed for accessing fields via properties, it will be "optimized" away by the JIT compiler (by inlining the code). Except when it is too large to be inlined, but then you needed the extra code anyway.
And the extra code for defining simple properties is also minimal:
public int MyProp { get; set; } // use auto generated field.
When you need to customize you can alway define your own field later.
So you are left with the extra layer of encapsulation / data protection, and that is a good thing.
My rule: expose fields always through properties
While I absolutely dislike directly exposing fields to the public, there's another thing: Fields can't be exposed through Interfaces; Properties can.
There are several reasons why you might want to use Properties over Fields, here are just a couple:
a. By having the following
public string MyProperty { get; private set; }
you are making the property "read only". No one using your code can modify it's value. There are cases where this isn't strictly true (if your property is a list), but these are known and have solutions.
b. If you decide you need to increase the safety of your code use properties:
public string MyProperty
{
get { return _myField; }
set
{
if (!string.IsNullOrEmpty(value))
{
_myField = value;
}
}
}
You can tell they're properties because they don't have (). The compiler will tell you if you try to add brackets.
It's considered good practise to always use properties.
There are many scenarios where using a simple field would not cause damage, but
a Property can be changed more easily later, i.e. if you want to add an event whenever the value changes or want to perform some value/range checking.
Also, If you have several projects that depend on each other you have to recompile all that depend on the one where a field was changed to a property.
Using fields is usually practiced in private classes that is not intended to share data with other classes, When we want our data to be accessible by other classes we use properties which has the ability to share data with other classes through get and set which are access methods called Auto Properties that have access to data in private classes, also you can use both with access modifiers Full Property in the same class allowing the class to use data privately as data field and in the same time link the private field to a property that makes the data accessible to other classes as well, see this simple example:
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
The private string _name is used by the class only, while the Name property is accessible by other classes in the same namespace.
why I would want to use properties instead of fields (especially when it appears I am just adding additional code
You want to use properties over fields becuase, when you use properties you can use events with them, so in a case when you want to do some action when a property changes, you can bind some handlers to PropertyChanging or PropertyChanged events. In case of fields this is not possible. Fields can either be public or private or protected, in case of props you can make them read-only publicly but writable privately.
any tips on recognizing the use of properties and not seeing them as simply methods (with the exception of the get;set being apparent) when tracing other peoples code?
A method should be used when the return value is expected to be dynamic every-time you call, a property should be used when the return value is not that greatly dynamic.
Any general rules of thumb when it comes to good programming methods in relation to when to use what?
Yes, I strongly recommend to read Framework Design guidelines for best practices of good programming.
Properties are the preferred way to cover fields to enforce encapsulation. However, they are functional in that you can expose a property that is of a different type and marshal the casting; you can change access modifiers; they are used in WinForms data binding; they allow you to embed lightweight per-property logic such as change notifications; etc.
When looking at other peoples code, properties have different intellisense icons to methods.
If you think properties are just extra code, I would argue sticking with them anyway but make your life easier by auto-generating the property from the field (right-click -> Refactor -> Encapsulate Field...)
Properties allow you to do things other than set or get a value when you use them. Most notably, they allow you to do validation logic.
A Best Practice is to make anything exposed to the public a Property. That way, if you change the set/get logic at a later time, you only have to recompile your class, not every class linked against it.
One caveat is that things like "Threading.Interlocked.Increment" can work with fields, but cannot work with properties. If two threads simultaneously call Threading.Interlocked.Increment on SomeObject.LongIntegerField, the value will get increased by two even if there is no other locking. By contrast, if two threads simultaneously call Threading.Interlocked.Increment on SomeObject.LongIntegerProperty, the value of that property might get incremented by two, or by one, or by -4,294,967,295, or who knows what other values (the property could be written to use locking prevent values other than one or two in that scenario, but it could not be written to ensure the correct increment by two).
I was going to say Properties (setters) are a great place to raise events like NotifyPropertyChanged, but someone else beat me to it.
Another good reason to consider Properties: let's say you use a factory to construct some object that has a default constructor, and you prepare the object via its Properties.
new foo(){Prop1 = "bar", Prop2 = 33, ...};
But if outside users new up your object, maybe there are some properties that you want them to see as read-only and not be able to set (only the factory should be able to set them)? You can make the setters internal - this only works, of course, if the object's class is in the same assembly as the factory.
There are other ways to achieve this goal but using Properties and varying accessor visibility is a good one to consider if you're doing interface-based development, or if you expose libraries to others, etc.
In my ASP.NET app, I have a Person and a PersonViewModel.
My Person was generated by LinqToSql. It has the properties that will be persisted in the database.
My PersonViewModel has everything Person has, plus a couple "select lists", which will be used to populate combo boxes, as well as a FormattedPhoneNumber (which is basically a PhoneNumber with dashes and parenthases added).
I originally just made Person a property on my PersonViewModel, but I was thinking that would mean the page would have to "know" whether something was a Person property or PersonViewModel property. For example, for name, the view would request pvm.Person.Name, but for the phone number, the view would request pvm.FormattedPhoneNumber. If I use inheritance, then everything the view needs would always be a direct property of the view model, hence pvm.Name.
This sounds great, but, there is no real "is-a" relationship here (i.e., I don't really think it makes sense to say "a PersonViewModel is a Person), and it seems to fly in the face of "preferring composition over inheritance". Still, I'm having difficulty thinking of a scenario where I'd need the ability to swap out a Person for something else. If I do this, it would no longer be a PersonViewModel.
What say you? Inherit from Person or keep Person as a property (or something else entirely)? Why?
Update
Thanks for all the answers.
It looks like the inheritance idea has been almost universally rejected, and for some sound reasons:
Decoupling the classes allows the ViewModel to contain only the properties from the domain model that are needed, plus any additional properties. With inheritance, you naturally expose all public properties from the domain model, which may not be a good idea.
The ViewModel doesn't automatically need to change just because the domain model changed.
As Jay mentioned, decoupling the ViewModel facilitates view-specific validation.
As Kieth mentioned, using a Mapper (such as AutoMapper) can eliminate a lot of the tedious work in mapping common properties between classes.
Deriving from an object implies an "is a" relationship. So in this case you would effectively be saying that a PersonViewModel is a Person. It seems that this is not likely to be the semantics that you really want to convey, so use composition instead of inheritance here.
In reality it probably doesn't really affect the maintainability of the application (other than having a few more dots here and there) but using composition certainly feels cleaner to me. In addition, if it's a PersonViewModel then presumably the view should know that that's the type it is dealing with.
Make Person a private member, and expose the properties that your view requires in the PersonViewModel, even if those properties just pass through the corresponding property of Person.
pvm.Person.Name is the code smell here.
Edit:
You're also limiting yourself to client-side validation and/or validation in the domain model, the latter meaning that if you create a second or subsequent ViewModel for Person, you can't change the validation on Person's members. (Well, you could, but this is a violation of the open-closed principle and you're introducing view concerns into the domain.) By hiding your domain objects from the view, you give yourself a clean space to perform use-case-specific validation before changes get made to your domain object. The domain object may have its own set of validators, but they can be strictly domain-appropriate, without view-specific issues creeping in.
You should not inherit from Person or use composition to have Person on PersonViewModel. Instead you should add the properties that you need to the PersonViewModel and map between them. Tools like AutoMapper (http://www.codeplex.com/AutoMapper) make this dead simple.
You should not expose your domain model directly to the View for a number of reasons, including security (under-posting and over-posting).
I am thinking a partial class may be better here. keep the generated Person class and add anothe partial Person class with the extra stuff in it.
On the one hand:
What if you did this?
Person p = new PersonViewModel { //init some properties };
Would p do everything you'd expect a Person to do? If it would, then sure, use inheritance. If it would have some peculiarities related to the fact that it's really a PersonViewModel, and not a Person, then use composition.
On the other hand:
My inclination is to use inheritance largely as a way of avoiding lots of duplicated code. Since you're only inheriting from one parent to one child (rather than to many children), you're not avoiding a lot of duplicated code in the first place. So it's probably not worth it to use inheritance.
One trick I've used, not specifically with ASP.NET MVC but with a similar use case, is to create a class that contains specifically those items specific to the ViewModel class (i.e., those that are not just tunneling through to the person class), and supplying an extension property on the Person class to allow access to the extended properties. This isn't strictly a ViewModel in the classic sense of the word, but I feel it allows for much of the same functionality without introducing awkward inheritance or code duplication with tunneled properties.
Here's a quick example of what I'm talking about:
public static class PersonExtensions {
public PersonViewData ViewData(this Person p) {
return new PersonViewData(p);
}
}
public class PersonViewData {
public PersonViewData(Person p) {
this._person = p;
}
private Person p;
public string FormattedPhoneNumber {
get { return p.PhoneNumber.ToPrettyString(); // or whatever }
}
}
I'm trying to find the equivalent of PropertyInfo.AddValueChanged for FieldInfo. I basically just need to receive an event any time the field's value changes. I'm assuming there's nothing like this and I'll have to manipulate IL code or something like that. I'm willing to go that route, but any suggestions on how I should go about it? And is there an AddValueChanged equivalent for fields that I'm not aware of so I don't have to go that route?
Thanks.
Why not just wrap the field in a property, and implement an event on change (ie: make your class INotifyPropertyChanged or your own equivelent)?
That's one the beautiful things about properties - they allow you to define behavior in this manner. Fields do not have any equivelent, and manipulating IL is not going to change this. As long as it's a field, it will not notify.
Let me just confirm that there's nothing built-in like what you're after. Properties can easily implement that because the setter is a method, while fields by design don't have setter methods, their value is just modified and that can happen from any place in the code. To do what you're after, I think you could take a look at PostSharp.
As indicated in the other answers, with the limited information you provided, I would suggest you make any value assignments via the field's accessor. If it needs to be outside of any class, you can create a separate class (or struc) (and put your field change in an accessor.) If you do not need multiple instances of the field, you can declare it static and only access it via its accesor.
Are you exposing public fields that you are trying to monitor? It seems like you should wrap them in properties and expose them that way. Then you can use the monitoring code you've already got.
I am currently hoping to use a PropertyGrid to allow users to edit some of my classes, however I've hit a wall with passing objects to the UITypeEditor(s) they use. When the user presses the drop down I want to show a listbox of already loaded textures to choose from, if they want to use a texture the application hasn't loaded yet they can click a button to choose one from a file dialog. In case I make no sense here a mock of the form:
.
My problem: To fill the listbox I need access to the class that manages the list of resources from the UITypeEditor.
Now I've solved this problem for my own classes by giving them a reference on creation to their managing object. In the UITypeEditor I then use that reference to access what I need. However I can't do this for classes I haven't written, such as the XNA Texture2D class.
Here are what the classes I'm using look like:
class StaticGeometryChunk
{
// Geometry data to draw with. Contains a reference to its managing
// class for use in its UITypeEditor.
public GeometryData { get; set; }
....
}
class Material
{
// These are XNA classes. I can't just add a reference to its managing
// class (I think?).
public Texture2D Texture1 { get; set; }
public Texture2D Texture2 { get; set; }
....
}
I've been looking at my options and they seem to be:
Make the managing classes static.
I don't really want to do this. There are several managing classes as each resource is loaded differently. There are also classes that need to be created before these and are passed in.
Make the managing classes singletons.
I don't really want to do this either. It seems like a quick and dirty way to "hide" the problem instead of "solve" it. I also might want the option of having several managing classes in the future which the singletons eliminate.
Create a wrapper class which holds the reference to a managing class and its target (such as the XNA Texture2D).
This is currently what I'm thinking of doing. Its would be quite simple and quick to do but something about it nags me but I don't know what.
Any thoughts on the above or other methods to pass what I need into the UITypeEditor?
Thank you for reading.
In the EditValue method, you are given a context. Use context.Instance to access the object that holds your property. This object should also contain a property that gives you access to the list of things you want to display. You could test if context.Instance is ITextureProvider for example, then cast it and access the textures. Not sure if this makes sense in your design but let me know.
As an alternative you can try the following approach. I find it very elegant, because it does not require to store a list of available property values in the object. Therefore, for example, you can show one set of values on one form and another set on another.
Create an interface IYourDataProviderService.
Create an implementation of IYourDataProviderService, which knows the concrete data to provide.
Create a class implementing ISite. In GetService() method return an instance of class which implements IYourDataProviderService, if the serviceType parameter is typeof(IYourDataProviderService).
I left rest of ISite methods throwing NotImplementedException (except DesignMode property) and for me it worked, but probably this is not an ideal solution.
In 'Load' event handler assign your implementation to the Site property of your propertygrid.
Enjoy!