C # add custom attributes for parent property in inherited class

I am showing a business object in generic DataGrids and I want to set the column header through a user attribute, for example:

class TestBo { [Header("NoDisp")] public int ID {get; set;} [Header("Object name")] public String Name { get; set; } } 

So far so good, but I would also like to separate my display from my data, inheriting:

 class TestBO { public int ID {get; set;} public String Name { get; set; } } class TestPresentationBO : TestBO { //Question: how to simply set the Header attribute on the different properties? } 

I see the solution through reflection using SetCustomAttribute in the Child constructor, but it will be cumbersome, so is there a simple and elegant trick for this problem?

Please do not let me violate data / presentation sharing; o)

+4
source share
6 answers

Just think, can you solve this with partial classes and MetadatatypeAttribute ? MVC2 uses this pattern to validate the model.

+1
source

Question: how to simply set the Header attribute for different properties?

It is not possible to set the attribute of an inherited element as you suggested, because the attributes are of type. SetCustomAttribute will not help you - it is only good when you create new types at runtime. After the attribute has been compiled, you cannot change it at runtime because it is part of the metadata.

If you want to keep the separation, you have to find another way.

(You can make the properties virtual, redefine them in the Presentation class and add attributes in the overrides, but it looks quirky and doesn't really separate anything - you still get the full test class in TestPresentationBO ..)

+6
source

Make properties in TestBo virtual and override them in TestPresentationBO . This way you can add attributes.

+3
source

You can do this as a WCF RIA service. Add an attribute to TestBO, for example [Presentation], using the type as a parameter. This new type will override properties, but with presentation attributes. At run time, you should get the identifier of the new type and get the custom attributes of its properties.

Or forget about the attribute and enter a dictionary matching BO with the presentation class BO. This presentation BO class does the same as above, that is, it overrides properties with custom attributes.

A presentation class BO is never created; it simply reflects on the receipt of presentation information.

+2
source

Are you using the MVVM model (model view representation model)? It seems to me, and in part from other answers, that you cannot do this with custom attributes as you want. But it also seems to me that your TestPresentationBO really looks like the "View Model" for TestBO . A view model is a kind of wrapper or surrogate for a business class or logical class, which is basically what you want. (This summary of the view model may not be 100% accurate; I'm just starting out with MVVM myself.)

You can create a TestBOViewModel to port a TestBO , and then pass the TestBOViewModel collection to the datagrid. Of course, you can decorate properties by exposing the wrapped class [Header("Object name")] , etc. This does not use inheritance, but I do not understand why you need to use inheritance in this situation. However, using the presentation model, it purely separates your presentation (presentation) from your data (model) using a wrapper (viewing model).

For more information on the MVVM pattern, I found this interesting: WPF applications with the Model-View-ViewModel design pattern .

Something like that. Of course, here you can add validation and other useful properties.

 public class TestBOViewModel // extend from DependencyObject { // if you want to use dependency properties private TestBO _myBO; public TestBOViewModel(TestBO bo) { _myBO = bo; } [Header("NoDisp")] public int ID { get { return _myBO.ID; } set { _myBO.ID = value; } } } 
+2
source

For C # 6.0, you can easily hide inherited elements and enter your own attributes. However, this may hide any attributes of the original property. In addition, this simplified syntax makes the property read-only, so you may need to pass get / set yourself.

 public class User { public string Login { get; set; } } public class UserDetail : User { [Display(Name = "Login:")] public new string Login => base.Login; } 
0
source

Source: https://habr.com/ru/post/1302724/


All Articles