I'm currently migrating an old forms application for MVC. The forms application has a property grid, which automatically binds to an object. The object has [Category] attributes assigned to each property. The object is also very complex.
Is it better to build the View for this from scratch or use reflection to generate the UI. Personally, I prefer to build it using HTML, but the object is very big. If it is still preferable to build the entire UI using #Html.TextBoxFor(), then that's the way I'll do.
Also, I might end up creating a ViewModel for this, but that's a maybe.
Thanks!
It depends! Do you have many similar objects that can benefit from reflection? Is that code is going to be reused many times over in different views? If yes, do reflection.
Otherwise path down reflection will take you more time to work out. And given that you already have required html, just use it! Keep it simple.
Related
I'm working with Unity C# for my personal project.
I have seperated Model and View. I want View to be automatically updated when somethings in model change.
So I made an Action object, and added all view-updating functions to it.
The thing is, there is super many fields in model. Adding the event to these fields would be really tedious job, and moreover, a single variable change will cause the whole UI to be updated, which may be a huge waste of perfomance.
But adding individual Action object to each of these fields would be much more tedious job.
All I want is that View is updated when Model is changed, and I think this event pattern is the best choice for my situation.
Are there any suggestions for my code design?
Unity has a great article on using ScriptableObjects to handle events like this. That being said, Unity uses an Entity-Component pattern, and retrofitting MVC pattern contradicts some of the optimizations that EC and Unity provide.
Using Protobuf-net, I want to know what properties of an object have been updated at the end of a merge operation so that I can notify interested code to update other components that may relate to those updated properties.
I noticed that there are a few different types of properties/methods I can add which will help me serialize selectively (Specified and ShouldSerialize). I noticed in MemberSpecifiedDecorator that the ‘read’ method will set the specified property to true when it reads. However, even if I add specified properties for each field, I’d have to check each one (and update code when new properties were added)
My current plan is to create a custom SerializationContext.context object, and then detect that during the desearalization process – and update a list of members. However… there are quite a few places in the code I need to touch to do that, and I’d rather do it using an existing system if possible.
It is much more desirable to get a list of updated member information. I realize that due to walking down an object graph that may result in many members, but in my use case I’m not merging complex objects, just simple POCO’s with value type properties.
Getting a delta log isn't an inbuilt feature, partly because of the complexity when it comes to complex models, as you note. The Specified trick would work, although this isn't the purpose it was designed for - but to avoid adding complexity to your own code,that would be something best handled via reflection, perhaps using the Expression API for performance. Another approach might be to use a ProtoReader to know in advance which fields will be touched, but that demands an understanding of the field-number/member map (which can be queried via RuntimeTypeModel).
Are you using habd-crafted models? Or are you using protogen? Yet another option would be to have code in the setters that logs changes somewhere. I don't think protogen currently emits partial method hooks, but it possibly could.
But let me turn this around: it isn't a feature that is built in right now, and it is somewhat limited due to complexity anyway, but: what would a "good" API for this look like to you?
As a side note: this isn't really a common features in serializers - you'd have very similar challenges in any mainstream serializer that I can think of.
The need to call FindViewById is a really messed up way to get the View inside an Activity. It may cause an exception at runtime, if the view does not exist in the layout.
Is there a layout generator to generate the Activity with all known Views as member variables (like in Windows.Forms or better WPF) in order to get Activities typesafe?
Cons
It's not typesafe
It's timeconsuming to implement
Not error prone, causing exceptions at runtime
Writing a lot of boilerplate code
Advantages
May have lower memory impact, when there are a lot unused Views, that don't need a member variable
A little better load performance.
So that instead of this:
EditText _editText;
// ...
_editText = FindViewById(Resource.Id.editText1);
_editText.Text = "Hallo World!";
I end up with just this:
_editText.Text = "Hallo World!";
The prefered way would be to utilize Androids Data Binding. But this is not available for Xamarin.
This is a really open ended question. There are many ways that can achieve type safety and obtain views.The best and most acceptable way is to use inflation at runtime, by putting the type you want into the views:
A self defined ViewGroup can be inflated into a Container. This is
done programmatically and you have "code-defined types" rather than
expected these types to exist in your XML document, or however you are
getting them. Look at
:How to Programmatically Add Views to Views
for implementation specifics (the same in Xamarin with some uppercases and what not).
You shouldn't really be making anything that will be problematic based off of the way you are calling functions and etc. I'd say really take a look at the way you are programming and make it more standard to the way Google(Android) and Microsoft(Xamarin) wants you to, and you won't run into as many problems like this. (I know this isn't helpful, but the question is super generic so just understanding the frameworks will make you come to good solution.)
Another great way is using the data binding Api's offered in Android and Xamarin : Android's Data Binding
So I am making a registration page in ASP.NET MVC and theres a list of fields which changes depending on a number of conditions (taken from a database).
What would be considered the best approach for displaying these fields on a view without code changes each time the DB is updated.
The current system I am thinking about is making a Dictionary with "Name, DataType" then just iterating through the list and putting a new input type of each name (using a switch for data type to get the correct editor). But it seems like a old fashioned and not fully utilizing the benefits of the .NET MVC system (such as validation, default values, customized editors for specific content).
Is there a approach I may possibly be not aware of in .NET to handle this problem?
I had very similar problem. Posting is here.
No, there is no polymorphism views in ASP.NET MVC. At least I couldn't make it work doing tons and tons of experimentation and asking this question several times in different ways on Stack Overflow.
The type of #model defined in the view will define its type inside the view, rather than actual type of the model (in case it was interface or abstract class or base class, while you passing in child class with all your beautiful decorations, which won't work, since type is defined by model type).
Sorry, no positive answer to your question. I ended up writing bunch of editor templates, which were only different by model type inside. Huge DRY violation, but this is the way ASP MVC worked, unfortunately.
Hope this helps saving you some time.
I am working on a Windows Forms app for quite some time now, and I really find myself doing more typecasts in the GUI code than I ever did in my underlying business code.
What I mean becomes apparent if you watch the ComboBox control that accepts some vague "object" as it's item.
Then you go off and may display some DisplayMember and a ValueMember and so on.
If I want to retrieve that value later I need to typecast my object back to what it was. Like with strings getting the value takes
string value = (string)combobox1.SelectedItem;
Since there are generics in the Framework for quite some time now, I still wonder why in the Hell not one control from the standard toolbox is generic.
I also find myself using the .Tag property on ListViewItems all the time to keep the displayed domain object. But everytime I need to access that object I then need another typecast.
Why cant I just create a ComboBox or ListView with items of type ListViewItem
Am I missing something here or is this just another example of not perfectly well thought through controls?
While the criticism of "didn't use generics" can't be fairly applied to controls developed before their existence... one must wonder about WPF controls (new in .NET 3.0, after generics in .NET 2.0).
I checked out the AddChild method in ComboBox. It takes an object parameter (ugh).
This control is intended to be used primarily via XAML. Was this done this way because there is no way to specify a type parameter in XAML? (aside, is there no way to specify a type parameter in XAML?)
Sorry to have no definitive "Why" answer, just sharing the common misery of needing to cast when working with the UI.
I dont think you're missing anything.
It's just that these classes were created back in the pre-Generics days, and WinForms is simply not cutting edge enough for MS to spend a lot of time changing or extending the API.
I often create wrapper classes for controls. This allows me to use generics. This is often in conjunction with Reflection, which is not type safe at compile time, but can be at run time.
A common source of this problem, I think, is not separating your view/presentation logic from your in-memory data model logic. Which, unfortunately, is an architecture fault that WinForms and the Visual Studio GUI designer are complicit in.
WinForms and the VS designer do not encourage the programmer to separate the management of their data objects from the form classes themselves. It would probably be better if the ComboBox ListViewItem objects didn't offer any support for arbitrary objects, either via generics or Object collections..
Unless you are hacking together something of limited use and lifetime, you should try to avoid storing references to individual data objects right in your controls or forms. They should be managed separately, and if they need to be referenced, it should be done via a model management class designed for the particular type of view class you're working with.
A simple-ish bandage for the problem, though, might be to "map" the text representations that you place into the ComboBox or ListView to the original objects, using a Dictionary field member on your Form class. It's not an ideal solution, but gives you at least a half-step of indirection between your data and your UI controls, which can make your code easier to maintain.
Edit: This is admittedly separate from the ListViewItemCollection class exposing Object instances... The official defense is likely to be that they wanted to support the standard IEnumerable and ICollection interfaces. But there's no reason they couldn't have also provided type-specific overrides of these methods, since it is designed explicitly to store ListViewItem instances. So I have no answer for you on that particular question.
Well, if you data-bind your controls to a DataBindingSource, you can get at your data that way, but AFAIK that's still not strongly typed. If you are displaying multiple parameters/aspects of a single business object, you can bind to that, then access the (strongly typed) members instead -- of course, this all goes back to Turbulent Intellect's answer, which is better separation between model and view. Still, I agree that generic-based typing would help.
It is possible (you can make your own generic controls, if you wish), but the form designer that comes with Visual Studio will freak out if you do this. You'll have to do stuff without it.
You aren't the first one to think of this, and Microsoft has already received a fair share of criticism from the public for this. Let's hope they add support for this in the future.