How make a view for editing different models' settings? - c#

This is an example of my general problem:
I have different implementations of ITextSearcher to search for something. Each implementation has different settings that can be edited by the user. So I can't make a general editable view for the implementations (because the settings can't be abstracted by an interface).
I have developed a simple library that helps in this situations. It allows to declaratively tag a class and it's properties with view information. A view generator uses this information to render the class. This is an example:
[Editable]
internal class TermSearcher : ITextSearcher
{
[Editable(Name="Search Expression", Order = 1)]
public string Expression
{...}
[Editable(Name="Match Similar Characters", Order = 2)]
public bool MatchSimilarChars
{...}
// rest of the implementation ...
}
Is there a better solution?

Yes. In WPF or Silverlight you can create a DataTemplate for the various instantiations of ITextSearcher. You can then use a DataTemplateSelector to pick the appropriate DataTemplate given an instance of an ITextSearcher
Since you tagged the post with MVVM I'm assuming you are using WPF

Related

Change current implementation of basic MVVM to adhere to SOLID pattern

I have been writing all my MVVM application with basic design pattern generally mentioned in MVVM examples available online. The pattern that I am following is described below:
Model
This section include DTO classes with their properties and Interfaces IDataService and like:
public class Employee
{
public string EmployeeName { get; set; }
public string EmployeeDesignation { get; set; }
public string EmployeeID { get; set; }
}
public interface IDataService
{
public Task<Employee> GetEmployeeLst();
}
Proxy
This layer contains Dataservice calls which implement IDataservice like:
public class DataService : IDataService
{
public async Task<Employee> GetEmployeeLst()
{
// Logic to get employee data from HTTPClient call
}
}
ViewModel
This layer contains ViewModel and reference to Model and Proxy layer from which all data is received:
public class BaseViewModel
{
public BaseViewModel(INavigationService nav, IDataService data, IAESEnDecrypt encrypt, IGeoLocationService geoLocation, IMessageBus msgBus, ISmartDispatcher smtDispatcher)
{
}
// This also include common methods and static properties that are shared among most of the ViewModels
}
All the ViewModel inherits BaseViewModel. Each viewModel also contains Delegatecommand which is executed when UI triggers an event. Which then fetches the data from the server by calling DataService in proxy layer and perform business logic and populates the properties in ViewModel which is binded to the view. For each View there is a VM which is binded to the Datacontext of the View.
ViewModel is also responsible for starting an animation I have used trigger to start storyboard which is binded to my enums in VM for state change of these trigger as in example in: http://www.markermetro.com/2011/05/technical/mvvm-friendly-visual-state-management-with-windows-phone-7/
View
In this layer I have all my Views, Usercontrols and business logic with implementation of certain dependencies like GeoLocation Service, AES encryption, NavigationService between Views etc.
Every View has .xaml and .xaml.cs file. In .xaml.cs file I have binded the data context of the view with VM like this:
this.DataContext = App.IOConatiner.GetInstance<DashboardViewModel>();
and from here on all binding happens.
My problem is that recently I had the knowledge that this pattern is not following a SOLID design pattern which I got know in this answer of my question:
Simple Injector inject multiple dependency in BaseClass
I am trying very hard to change my design as per the suggestion given in my previous question's answer. But I am not able to get some of the things like:
Currently View Datacontext is binded to ViewModel hence all the controls are controlled by a property in VM. How would I change this to your above mentioned pattern with Processor/Service or DialogHandler?
I am using Delegatecommands which are binded to command property of UI element. Execution of these command certain action happens like animation, usercontrol is displayed. How to do it in command pattern?
How can I start changing my current implementation to accommodate all those changes with best possible approach?
First of all an answer to your question 3
How can I start changing my current implementation to accommodate all those changes with best possible approach?
This is the very first step you need to take. It is not a case of some smart refactoring of your current code. You will need to take a step back and design the application. I once read some nice blog about (re)design.
Before starting to write any code, define how many different basic types of views you will want to show to the user? E.g.:
Just show (any type of) data
Edit data
Alert user
Ask user for input
...
When you defined your different requirements, you can translate this to specific interfaces that are tailor made for the job they serve. For example a view that lets the user edit data will typically have an interface that will look something like:
public interface IEditViewModel<TEntity>
{
public EditResult<TEntity> EditEntity(TEntity entityToEdit)();
}
Once you every detail of this design in place, you must decide how you will show your views to the user. I used another interface for this to handle this task for me. But you could also decide to let a navigation service handle this kind of task.
With this framework in place, you can start coding your implementations.
Currently View Datacontext is binded to ViewModel hence all the controls are controlled by a property in VM. How would I change this to your above mentioned pattern with Processor/Service or DialogHandler?
This will not change in this design. You will still bind your view to your viewmodel and set the datacontext to the viewmodel. With a lot of views the use of an MVVM framework like Caliburn Micro will come in handy. This will do a lot of the MVVM stuff for you, based on Convention over Configuration. To start with this model, would make the learning curve even higher, so my advice to start of by hand. You will learn this way what happens under the covers of such an MVVM tool.
I am using Delegatecommands which are binded to command property of UI element. Execution of these command certain action happens like animation, usercontrol is displayed. How to do it in command pattern?
I'm not sure if the command pattern you mention here is the command pattern I advised you in the previous answer. If so, I think you need to reread this blog, because this is totally unrelated to the commands I think you mean in this question.
Animation and that sort of stuff is the responsibility of the view, not the viewmodel. So the view should handle all this stuff. XAML has a lot of ways to handle this. More than I can explain here. Some ideas: Triggers, Dependency Properties
Another option: Code behind! If the logic is purely view related IMO it is not a mortal sin to place this code in the code behind of your view. Just don't be temped to do some gray area stuff!
For commands that just perform a method call in your viewmodel, ICommand is still possible and MVVM tools like Caliburn will do this automagically...
And still: Loose the base class....
Why are you injecting all these services in your viewmodel base class if the viewmodel base class does not make use of these services himself ?
Just inject the services you need in the derived viewmodels that do need those services.

Decorator Pattern vs Inheritance with examples

I've been experimenting with the decorator pattern to extend functionality of code you do not want to touch for example and I see how to implement it however I am now unsure why you don't just inherit from the original class and extend that way.
I have read that the decorator pattern allows you to add functionality at runtime whereas inheritance means its there at compile time.
I don't understand this.
Could someone explain this, provide examples and explain when its better to use decorator vs inheritance.
Thanks
Suppose you create a View class that displays your items in a certain way.
Now you decide you also want a version of it which is scrollable, so you create a ScrollableView which inherits the View.
Later you decide you also want a version with a border so you now need to make a BorderedView and a BorderdScrollableView.
If on the other hand you could make a decorator for each added styling. You would have the following classes:
View
ScrollableDecorator
BorderedDecorator
When you want a bordered scroll view you do:
new BorderedDecorator(new ScrollableDecorator(new View())).
So you can configure any combination of this with just the 3 classes. And you can add or remove them at runtime (suppose you click a button that says add border, you now wrap your view with a BorderDecorator ... while whith inheritance you need to implemented this view class if you haven't already, or you need to create a new view instance and copy all relevant data from the first view to the second view which is not as easy to do as just adding or removing wrappers).
Imagine a game like Civilization, where each square on the map can have a variety of resources attached to it (like, say, various ores, or wood, or oil, etc.).
If you used straight inheritance, you'd need to create a class for each kind of square. It'd be unwieldy to have
public class OilSquare {}
public class OilAndGoldSquare {}
public class GoldAndSilverSquare {}
// etc.
The Decorator Pattern allows one to mix and match without needing to create a rigid hierarchy. So, you'd have instead:
public class Square {}
public class GoldDec {}
public class SilverDec {}
public class OilDec {}
// ...
var crazyMix = new GoldDec(new SilverDec(new OilDec(new Square())));
Put another way, Decorators allow for the creation of pipeline behavior, with each step in the pipeline being swappable with another step.
As others have already said Decorators are good for adding "options" to things... The benefits come in the way you can chain methods etc. through the decorators.
Imagine I buy a car with options for leather interior, metallic paint and awesome spoiler...
There are 8 different combinations of the three options but with decorators you only need three extra classes.
The interesting thing though is the way the decorator pattern works. As a brief example:
public class MetallicPaint : Car
{
private Car car;
public MetallicPaint(Car wrappedCar)
{
car = wrappedCar;
}
public decimal Cost()
{
return car.Cost() + 500;
}
public string Description()
{
return car.Description() + ", Metallic Paint";
}
public string Speed()
{
return car.Speed();
}
[... {pass through other methods and properties to the car object}]
}
This isn't a complete example but highlights how the decorator can interact with the object it is decorating. And of course because it implements car it can be used just like a car in every other way (and passes through anything the decorator doesn't effect to the inner car object).
Of course if you had multiple of these decorators with a car nested inside each would in turn add their cost, their part of the description and maybe the spoiler would alter the speed whereas the others didn't...
In essence it allows you to modify an object in a much more modular and less fundamental way than inheritance would. Decorators should always be used as if they were the base object (in this case Car) so they should never expose any new methods or properties, just slightly change the effect of existing ones.
Decorator pattern is better than inheritance if you have many features to be added and you also require to have combination of these features. Suppose your base class is A, and you want to extend(decorate) this base class with feature f1,f2,f3,f4 and some combination of them like (f1,f2) and (f1,f3) and .. ; so you would require to create 4!=4*3*2*1=24 class in your hierarchy (4 for each feature and the rest for their combination). While, Using decorative pattern, you would only need to create 4 classes!
for #Seyed Morteza Mousavi in #Razvi post:
You are right, we can add two properties Scrollable and Bordered to View class, then check if the property is set to true so run the desired behaviour. But this requires that we already be aware of the number of the feature we require(which is not the case in decorator pattern). otherwise, with every new feature (say f1) we want to add to our class, we need to alter our main class, or inherit the main class (you would say) and add the property. Taking latter approach, you would further need to alter the part of the code which handles feature combination (this is not good, since it is not obeying the rule of thumb of "loose coupling!")
hope this helps.

How would I create composite settings for an application?

What I would like to do is have a versatile settings class that I can use in a composite application. As I add features and components and compose the application using MEF & Prism I would like to have a settings window that automatically loads the settings interface of each of the modules into a window (using Prism & MEF)
There are many different ways of dealing with settings, and the one that appeals to me is something along the following:
public class AppData : ApplicationSettingsBase
{
[UserScopedSetting()]
[DefaultSettingValue("true")]
public bool Clipboard
{
get { return ((bool)this["Clipboard"]); }
set { this["Clipboard"] = (bool)value; }
}
}
It allows me to set a default value and I am assuming that if the application does not find the .settings file then it will create one with the defaults. However I would need to write a bunch of custom code for each modules settings section and either create a unique dialog for each module or try to have a settings manager that manually loads them all in.
There are some settings that would have multiple values as well and it does not look like the above example would be able to accomodate that. What if I had a setting that stored a list of something? For example if I had a setting that was ValidBlock, and at the start there are two blocks that could be valid but in the future there may be a need to add more? Can you have a setting that is a list and specify multiple default values for that setting?
So would it be acceptable to create a Isettings interface that somehow used ApplicationSettingsBase so that I can use MEF to find all Isettings implementations in all the modules in a directory and then compose a dialog with tabs for each implementation it found? In the Isettings interface I could have some basic properties such as Name and whatever else would be needed to label and describe the module in the MEF WPF window.
The only other thing I do not like is that there are strings and attributes all over the place. Is there a way to deal with settings in a fluent way? I am thinking along the lines of having a ISettings implementation that you would explicitly code a setup something like the following:
public class AppData : ISettings
{
Setting Clipboard = new Setting();
Clipboard.Scope = SettingScope.User;
Clipboard.SettingType = List<String>;
List<String> DefaultClipboards = new List<String>();
DefaultClipboards.Add("FoxClipboard");
Clipboard.DefaultSetting = DefaultClipboards;
}
I know the above is not exactly syntax correct, and I do not think that the Clipboard.SettingType would hold much water but its to give an idea of what I am thinking. So if something like this can be achieved while maintaining the creation of a settings file in the event one is missing that would be ideal. As well with something like this MEF can find all the ISettings implementations and create a tab for each one, and then add each Setting based on setup of it in the code.
Is this the right track to be on? Is there a framework or project out there that I have missed that handles what I am aiming for? I am thinking there is probably a better way than what I have outlined?
I am sure this question has come up in composite application development but I have not found a framework or an answer that outlines this scenario.
I have been able to create a loose coupled composite application and dynamically wire up my modules using MEF & Prism but I have not been able to find a satisfactory way to deal with settings in a composite way.
I tackled something similar for one of my applications at work. We leaned further towards your second idea, where there is simply a base settings interface "ISettings" that we used for MEF composition.
We created a custom export provider to deal with loading settings, and had a manager to save out the settings using some serializer.
For the UI, we had modules with user facing settings also export a "settings workspace" that we would load into the settings UI. Using reflection, we wrote a method that will make a deep copy of a settings object so that we could do direct mvvm binding to the cloned object (for cancel functionality), as well as take an object and copy it's properties back.
The reflection was to allow for a generic clone/copy without writing code for every settings object.
Also, one thing that we did that I still love to this day for data model binding is the "INotifyPropertyChanged" interface. Our base ISettings object requires it. This allows not only the settings UI to directly bind to settings and listen for changes, but when we hit apply or ok, all of our data model that needs settings registers for the prop changed event, so they all automatically get notified when a setting has changed.
Check out Property Observer if you plan on doing the notify route. This application has been deployed and I still feel like our settings framework is wildly successful.
If you need, I can provide further detail in certain areas.
Hope this helps!
Disclaimer: I have no experience with custom implementations of ApplicationSettingsBase so I can not assist with its actual implementation, nor positively say that this approach will work. However, what I propose might be a path worth exploring if you really want to use ApplicationSettingsBase.
First of all, ISettings can not inherit ApplicationSettingsBase, because interfaces can only inherit other interfaces.
My proposal is to create a custom ApplicationSettingsBase implementation that is parameterized with an instance of ISettings. That way, whenever you recieve an ISettings from your components, you instantiate a new CustomAppSettings (see below) and associate that with your component.
Since ApplicationSettingsBase uses a string-to-object key value pair mapping, I propose an interface that does the same.
public interface ISettings
{
Dictionary<string,object> Values{ get; set; }
public object GetDefaultValue(string key);
// Whatever else you might need
}
public class CustomAppSettings : ApplicationSettingsBase
{
public ISettings Settings { get; set; }
public override object this[string propertyName]
{
get
{
return this.Settings.Values[propertyName];
}
set
{
this.Settings.Values[propertyName] = value;
}
}
// There will be more implementation work for this class I'm sure
}
In addition you would need a serialization mechanism for your ISetting instances.
Edit: Fixed some code syntax errors

Dynamic data-entry forms in Silverlight

We are investigating how to create data entry views from a dynamic list of pre-defined field definitions. By "pre-defined", I mean that there are only 8 basic field types. The Silverlight Toolkit's DataForm control is almost what want, but it targets object properties (not a list of custom definitions).
Is there an existing project to make this easy? Please comment on my design idea (below). I have only ~2 weeks Silverlight experience.
Basic design idea:
I am thinking of defining custom data field types. An IEnumerable<BaseDataField> will be received by the UI, enumerated, and controls will be created based on the type of each field. Each field will create a label with the description and BooleanDataField will create a CheckBox, LookupDataField will create a ComboBox, etc.
Pseudo code to clarify the idea:
public abstract class BaseDataField {
public string FieldCode { get; private set; }
public string FieldDescription { get { return FieldDefinitions.Instance.FieldDescription(FieldCode); } }
...
}
public class StringDataField : BaseDataField
public class BooleanDataField : BaseDataField
public class CurrencyDataField : BaseDataField
public class IntegerDataField : BaseDataField
public class NumericDataField : BaseDataField
public class DateTimeDataField : BaseDataField
public class LookupDataField : BaseDataField
public class SpecialDataField : BaseDataField
This will be extended to make the fields bindable; allow specifying custom controls for each type; and have validation feedback.
Can it be easily done in Silverlight or should we create a custom control?
Note: This programme will be a web UI for an existing, multi-tier LOB platform. All data is serialised from a JSON-based REST service.
Thanks!
I would highly recommend incorporating the DataForm class into your solution and it is indeed capable of handling custom controls. I've been chasing this goal of an ideal minimal-xaml data form for years and I have finally settled on what I think is a great combination of the built-in functionality of DataForm and custom fields derived from DataField. For example, I just extended DataField so that when no Content property is specified, it automatically uses a TextBox which minimized my XAML big time. I also added support for the DisplayFormatAttribute which DataForm doesn't seem to support natively.
Anyhow, what you could do first is create a bunch of subclasses like you describe above and derive from DataField. Then in the OnApplyTemplate method, create an element to represent the data. For example:
class BooleanDataField : DataField {
protected override void OnApplyTemplate() {
if (this.Content == null) {
var check = new CheckBox();
check.SetBinding(CheckBox.IsCheckedProperty,
new Binding(this.PropertyPath));
this.Content = check;
}
base.OnApplyTemplate();
}
}
As for how to get your field metadata loaded by DataForm, you have a few options. You could handle the AutoGeneratingField event and look up the appropriate field to use on the fly or you can disable auto field generation and just load it up with your own.
We started with DataForm, but ended up overriding everything that makes it useful and still had some problems. I learned a great deal from the attempt and eventually built a custom control for the job. Unfortunately this solution is not very extensible...

C# add custom attributes for a parent's property in an inherited class

I'm displaying Business Object in generic DataGrids, and I want to set the column header through a custom attribute, like:
class TestBo
{
[Header("NoDisp")]
public int ID {get; set;}
[Header("Object's name")]
public String Name { get; set; }
}
So far, so good, but I'd also want to separate my display from my data, by inheritance:
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 a solution via reflection with a SetCustomAttribute in the Child constructor, but it will be cumbersome, so is there a simple and elegant trick for this problem?
Please prevent me from breaking the data/presentation separation ;o)
Question: how to simply set the Header attribute on the different properties?
There is no way to set an attribute on an inherited member the way you have suggested, since attributes are specific to a type. SetCustomAttribute won't help you - it's only any good when you construct new types at runtime. Once an attribute has been compiled in you cannot change it at runtime, since it's part of the metadata.
If you want to maintain the separation you will have to find another way.
(You could make the properties virtual, override them in the Presentation class and add attributes on the overrides, but this looks dodgy and doesn't really separate anything - you end up with a complete TestBO class in your TestPresentationBO anyway...)
Make the properties in TestBo virtual and override them in TestPresentationBO. That way you can add the attributes.
Just thinking, can't you solve this with partial classes and the MetadatatypeAttribute? MVC2 uses this pattern for Model validation.
You can do it like WCF RIA Services. Add an attribute to TestBO, like [Presentation] taking a type as parameter. This new type will redefine the properties, but with the presentation attributes.
At run-time, you have to get the identity of the new type and get the custom attributes of its properties.
Or forget about the attribute and have a dictionary mapping the BO with the presentation BO class. This presentation BO class does the same thing as above, i.e. redefine properties with custom attributes.
the presentation BO class is never instantiated, it is simply reflected upon to get presentation info.
Are you using the MVVM (model view view-model) pattern? It seems to me, and partly from the other answers, that you can't really do this with the custom attributes like you want. But, it also seems to me that your TestPresentationBO is really just like a "View Model" for TestBO. A view model is basically a sort of wrapper or surrogate for a business or logic class--which is basically what you want. (This summary of a view model may not be 100% accurate; I'm just starting out with MVVM myself.)
You can create a TestBOViewModel to wrap TestBO, then pass the collection of TestBOViewModel to the datagrid. Of course, you can decorate the properties exposing the wrapped class with [Header("Object's name")] etc. This doesn't use inheritance, but I don't see why you'd need to use inheritance in this situation. Using a view model, does, however, cleanly separate your presentation (view) from your data (model) by using the wrapper (view model).
For more info on the MVVM pattern, I found this to be an interesting read: WPF Apps With The Model-View-ViewModel Design Pattern.
Something like this. Of course, you can add validation and other goodies in here too.
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; }
}
}
For C# 6.0 you can easily hide inherited members and introduce your own attributes. This might, however, hide any attributes on the original property. Also this simplified syntax makes the property read-only, so you might need to pipe the get/set yourself.
public class User
{
public string Login { get; set; }
}
public class UserDetail : User
{
[Display(Name = "Login:")]
public new string Login => base.Login;
}

Categories