I have taken over a project, that have been coded by someone else. There are weird stuff in it like this: An interface declaring a custom event named Load ( event EventHandler Load; )
Since the Form class has its own Load event, what is supposed to happen when this interface is implemented? Is it some form of overriding the default event, if so what purpose does it serve to?
thx in advance
Well, the interface declaration isn't actually writing any code, it's just forcing an implementation. So given that the form already implements it, if the interface is applied to the form, it will just "implement" the interface, by virtue of it already being there! So it has no negative affect.
What purpose does it server? Perhaps the person provides that interface to other people, who only need to know that the underlying object is of type IWhateverItIs, and can attach to the Load event appropriately.
Related
In my view-model i have an command which implements print operation using PrintVisual of PrintDialog class . As i don't have the access to the view i cannot print it .how should tackle this ?
Is there an easier and better approach?
I think your solution would be to pass a service class in that performs the work of printing the grid, showing a dialog, and whatever work is required to get the job done.
In MVVM, most of people use dependency injection to do this. You would create another service with the same interface for your tests to use that wouldn't block execution. The service, in this case, is a view layer service, and should have no dependency back to the viewmodel. The only thing the viewmodel knows is that it has a service interface to call into, and the only thing the service knows about the viewmodel is the interface it implements for this interaction.
I read this Wikipedia article that has helped me in the past:
SOLID - Wikipedia
Let me know if this makes sense.
This is how i solved it.
I created an event in my viewmodel. Raised the event here whenever i want to print operation.
I defined my listener method in the mainwindow.xaml (this is where i have defined my content presenter , and all the data templates are being assigned to this contentpresenter.content)
In this listener method i am calling the print operation using PrintVisual of PrintDialog Class.
!
let's say that in my application, there is an user interface for representing a (geographic) map. It is integrated into the application as a UserControl and has its view model behind it.
Now, suppose I want to provide other parts of my application with a generic service interface to perform common tasks on the map (zoom, pan etc.) and not worry about the UI specifics. I could give away direct reference to the viewmodel, but I am pretty sure I would violate separation of concerns principle, not to mention it would be less testable.
So there are few questions:
Does it make sense and is it good practice to implement such services (which act as an intermediate link to the UI) in the first place?
Since the service operates directly on the map's viewmodel, should it be the viewmodel itself which implements the service interface?
Is it appropriate for the service interface to provide events (e.g. besides providing a method to change the map scale, provide an event that the map scale was changed as well)? Or is it preferable to employ some kind of event broadcaster (aggregator) mechanism to push such notifications out of service interfaces?
Thanks in advance for your help.
Consider using the Messenger in the MVVM Light toolkit. See more in another SO answer:
https://stackoverflow.com/a/2700324/117625
EventAggregator is the another mechanism which establish communication between disconnected view models. I believe all the other parts of your application will be using the same MVVm and will have viewmodel to do the operations. Publish event say Zoom with required arguments from other parts of the app and catch it in the map using the subscribe mechanism.
http://msdn.microsoft.com/en-us/magazine/dd943055.aspx#id0420209
Prism has a good implementation of Event Aggregator. you can use that part.
Whenever you need two view models to communicate (or something similar, such as a button that wants to invoke a command on a view model other than its own), the best practice I've found is use a messaging channel. (MVVM Light has the Messenger class; Prism and Caliburn.Micro both have an EventAggregator.) When the target of the command is instantiated (your map view model), it will register for specific commands on a messaging channel. When an invoker (such as a button) is instantiated, it can then send commands over that same channel. This keeps your components loosely coupled. Commands from the messaging channel can be easily mocked for unit testing. It also opens up other avenues to you, such as having multiple maps open at the same time (simply use a different messaging channel or some sort of token).
I'd skip the whole service interface in your case. When using an event aggregator, it doesn't really add much. Depending on the size and complexity of your code base, you might want to keep it around so it describes the commands available for a map, but that only makes sense if you have more than a handful of commands. In that case the service would register as the end point for commands on the messaging channel and would then have to forward those commands on to a map view model. (See? Doesn't add much and only seems to complicate things.)
Skip the events. They don't seem to add anything.
What if you had an aggregate Command object which specified the appropriate behaviour? I'm going to try to flesh your question out a little bit to specifics, correct me if I'm wrong:
Let's suppose that there are two relevant parts of your app - a map component, which can be zoomed and panned etc, and a set of controls, which present the user interface for zooming, panning and selecting between them - sort of a set of mode selectors. You don't want either of them to have a direct reference to the other, and the temptation is to have the map know directly about its set of controls, so that it can catch events from them and switch mode state appropriately.
One way to take care of this would be to have a set of CompositeCommands (available from the Prism Application Guidance) libraries inside an object injected into each of them. That way you get decoupling and a strong description of interface (you could also use events if you were that way inclined).
public class MapNavigationCommands{
public static CompositeCommand startPanning = new CompositeCommand();
public static CompositeCommand startZooming = new CompositeCommand();
public static CompositeCommand setViewbox = new CompositeCommand();
}
Your mode controls, up in the Ribbon, register with your DI framework to have that injected (not wanting to introduce DI into this example, I've just referenced these static members directly).
public class ModeControls : UserControl{
...
public void PanButtonSelected(object sender, RoutedEventArgs e){
MapNavigationCommands.StartPanning.Execute(this); //It doesn't really care who sent it, it's just good event practice to specify the event/command source.
}
}
Alternatively, in XAML:
...
<Button Command={x:Static yourXmlns:MapNavigationCommands.StartPanning}>Start</Button>
...
Now, over on the map side:
public class PannableMapViewModel{
public PannableMapViewModel(){
MapNavigationCommands.StartPanning.RegisterCommand(new DelegateCommand<object>(StartPanning));
MapNavigationCommands.SetViewbox.RegisterCommand(new DelegateCommand<Rectangle>(SetViewBox));
}
private void StartPanning(object sender){
this.SetMode(Mode.Pan); //Or as appropriate to your application. The View is bound to this mode state
}
private void SetViewbox(Rectangle newView){
//Apply appropriate transforms. The View is bound to your transform state.
}
}
Now you have a decoupled, strongly specified interface between two controls, maintaining ViewModel separation, which can be mocked out for your tests.
I am writing a fairly large scale WPF desktop application using the MVVM pattern. I have been stuck for a while on getting my common properties to update in a View other than the one that updated it.
I have a RibbonWindow MainView that contains a ContentControl that displays the remaining Views one at a time dependant on the user's selection. I have a BaseViewModel class that all the ViewModels extend. Among other things, this class exposes the INotifyPropertyChanged interface and contains a static property of type CommonDataStore. This class also implements the INotifyPropertyChanged interface and contains the properties that are to be available to every ViewModel.
Now, although I can access and successfully update the CommonDataStore properties from any ViewModel, the problem is that the WPF Framework will only notify properties that have changed in the current View. Therefore, although the common values have been updated in other ViewModels, their associated Views do not get updated.
One example from my application is the login screen: As the user logs in, my LogInView updates with the new information (ie. full name) from the database, but the user details in the MainView do not.
After reading a few other posts, I also tried implementing the CommonDataStore class as a Singleton, but that didn't help. I could also just pass a reference to this common data object to the constructor of each ViewModel from the MainViewModel, but I'm not sure if this is the right way to go.
I have also discovered that in WPF, static properties are treated a bit like constant values. It seems that they just read the value once.
So anyway it's clear, my attempts have all failed. I was wondering what the standard way of doing this was? In particular, I need to be able to bind to the common properties and have all of my ViewModels and Views update when any common value is changed. Any help would be greatly appreciated. Many thanks in advance.
Edit >> Really? No one uses application wide variables in an MVVM WPF application?
I have now removed the static part of the Common property declaration and am simply passing a copy into each ViewModel individually. This seems to work, but I'd really like to know how others approach this situation. Please answer by simply letting me know how you organise this application wide data.
I have done something similar to what you describe last. I have class called SecurityContext that holds some of the application-wide data. One instance is created when the application starts up and then that instance is passed into the constructors of all the ViewModels through dependency-injection. I have a base class for ViewModels which exposes that object through a regular instance property (implementing INotifyPropertyChanged).
Have you looked into implementing the Observer Pattern? We have done so with IObservable and IObserver. This describes the "IObservable/IObserver Development Model" as follows:
The IObservable/IObserver development model provides an alternative to using input and output adapters as the producer and consumer of event sources and sinks. This model is based on the IObservable/IObserver design pattern in which an observer is any object that wishes to be notified when the state of another object changes, and an observable is any object whose state may be of interest, and in whom another object may register an interest. For example, in a publication-subscription application, the observable is the publisher, and the observer is the subscriber object. For more information, see Exploring the Observer Design Pattern on MSDN.
I am starting my first foray into the world of Prism v4/MVVM with MEF & WPF. I have sucessfully built a shell and, using MEF, I am able to discover and initialise modules. I am however unsure as to the correct way to provide navigation to the views exposed by these modules.
For example, let's say that one of the modules exposes three views and I want to display navigation to these views on a menu control. So far, I have sucessfully exposed a view based upon a MenuItem and this MenuItem contains child MenuItem controls thus providing a command heirarchy that can be used. Great.
Thing is, this feels wrong. I am now stating within my module that navigation (and therefore the shell) MUST support the use of menu's. What if I wanted to change to using a ToolBar or even a Ribbon. I would then have to change all of my modules to expose the corresponding control types for the shell.
I have looked around and there is mention on some sites of using a "Service" to provide navigation, whereby during the initialisation of the module, navigation options are added to the service which in turn is used by the shell to display this navigation in whatever format it wants (ToolBar, TreeView, Ribbon, MenuItem etc.) - but I cannot find any examples of actually doing this.
To put all of this into perspective, I am eventually looking to be able to select views from a menu and/or other navigation control (probably a Ribbon) and then open those views on demand within a TabControl. I have already gotten as far as being able to create the views in the TabControl at module initialisation time, now I need the next step.
What I need to know is this: what would be the correct way to expose navigation options in such a way as not the insist on support of a specific control by the shell, and if a service is the way to go then how would one put this together within the Prism/MVVM patterns.
Thanks in advance for any insight you can offer.
I suppose you have a main module containing common interfaces.
You could create a simple interface like
public interface IMenuService {
void AddItem(string name, Action action);
IEnumerable<MenuItemViewModel> GetItems { get; }
}
Create 1 implementation and a single instance.
public class MenuService : IMenuService {
private readonly IList<MenuItemViewModel> items = new List<MenuItemViewModel>();
void AddItem(string name, Action action) {
items.Add(new MenuItemViewModel {
Name = name,
Action = action
});
}
IEnumerable<MenuItemViewModel> GetItems {
get { return list.AsEnumerable(); }
}
}
Within your modules, use MEF to resolve this instance and call AddItem() to register your views.
The Action property is a simple delegate to activate a view or do anything else.
Then in your shell or any view, you just need to call the GetItems property to populate your menu.
Having thought about this some more, I have come to the following conclusion that I feel affects the way that I need to deal with this...
The modules need to be partially aware of the shell layout anyway - that is, the shell exposes a number of regions and the modules need to be aware of those regions (by name as well as what is expected to be shown) in order to populate them correctly when functionality is requested (either by means of registering a view within a region or as the reaction to a user action).
Because of this, the modules need to be designed to interact with the shell to place content into the named regions and as such, I see no reason why the modules should not expose whatever type of navigation the shell supports.
Therefore, my modules (currently) expose a "RibbonView" (a RibbonTab) with the necessary icons, buttons and commands etc to expose the functionality of the module. Each "RibbonView" is registered with the "RibbonRegion" of the shell, along with hints for ordering, and this is then rendered within the shell.
If in the future I choose to update my shell to use the latest+greatest navigation control (whatever that may be in x years time) then I simply need to update each of the modules to expose the necessary items to integrate with that new navigation and, because I am loading into a new shell, I can then update my view registration accordingly.
I just hope that I am not breaking any of the principles of the composite application in doing this, but that said I have never yet found a pattern that can actually be implemented in a real scenario without some "interpretation".
I would be interested to hear if anybody has any opinions on this.
I've encountered the same situation, and I think the solution lies in differentiating between interface and implementation. For example, you can design a view in a module that performs a given function. That's all it does. As soon as you use or consume this in a specific context you've crossed over into implementation. Now, ideally the view is unaware of how it's being implemented, and certainly would have no knowledge of named Regions in the Shell. So, seating views into Regions within a module is a no-no.
To get around this, I've opted to delegate this responsibility to a third-party component, a LayoutManager. The LayoutManager sits between the Shell and Module and defines "what goes where". It is a specific implementation, and really defines the implementation. Both the Shell and the Module view remain generic.
Have a look at: http://rgramann.blogspot.com/2009/08/layout-manager-for-prism-v2.html
Which may give you some ideas around this problem.
Hope it helps.
This article uses an abstraction (IMenuItem) to represent the ViewModels for your menu choices. How you actually render these imported objects is really up to the host application. The example uses a WPF menu, but you could certainly render it any way you wanted because IMenuItem is abstract enough.
If you changed IMenuItem to INavigationItem, you've got what you want.
In that article, when the particular navigation item gets notified that it's been "run", then it usually instantiates a ViewModel for a document or "pad", and passes that to the ILayoutManager service. It has a pluggable architecture, so you can swap out the LayoutManager service for a different layout engine (the default one is a wrapper around AvalonDock).
I have an MVVM application. In one of the ViewModels is the 'FindFilesCommand' which populates an ObservableCollection. I then implement a 'RemoveFilesCommand' in the same ViewModel. This command then brings up a window to get some more user input.
Where/what is the best way to do this whilst keeping with the MVVM paradigm? Somehow
doing:
new WhateverWindow( ).Show( )
in the ViewModel seems wrong.
Cheers,
Steve
I personally look at this scenario as one where the main window view model wants to surface a task for the end user to complete.
It should be responsible for creating the task, and initializing it. The view should be responsible for creating and showing the child window, and using the task as the newly instantiated window's view model.
The task can be canceled or committed. It raises a notification when it is completed.
The window uses the notification to close itself. The parent view model uses the notification to do additional work once the task has committed if there is followup work.
I believe this is as close to the natural/intuitive thing people do with their code-behind approach, but refactored to split the UI-independent concerns into a view model, without introducing additional conceptual overhead such as services etc.
I have an implementation of this for Silverlight. See http://www.nikhilk.net/ViewModel-Dialogs-Task-Pattern.aspx for more details... I'd love to hear comments/further suggestions on this.
In the Southridge realty example of Jaime Rodriguez and Karl Shifflet, they are creating the window in the viewmodel, more specifically in the execute part of a bound command:
protected void OnShowDetails ( object param )
{
// DetailsWindow window = new DetailsWindow();
ListingDetailsWindow window = new ListingDetailsWindow();
window.DataContext = new ListingDetailsViewModel ( param as Listing, this.CurrentProfile ) ;
ViewManager.Current.ShowWindow(window, true);
}
Here is the link:
http://blogs.msdn.com/jaimer/archive/2009/02/10/m-v-vm-training-day-sample-application-and-decks.aspx
I guess thats not of a big problem. After all, the Viewmodel acts as the 'glue' between the view and the business layer/data layer, so imho it's normal to be coupled to the View (UI)...
Onyx (http://www.codeplex.com/wpfonyx) will provide a fairly nice solution for this. As an example, look at the ICommonDialogProvider service, which can be used from a ViewModel like this:
ICommonFileDialogProvider provider = this.View.GetService<ICommonDialogProvider>();
IOpenFileDialog openDialog = provider.CreateOpenFileDialog();
// configure the IOpenFileDialog here... removed for brevity
openDialog.ShowDialog();
This is very similar to using the concrete OpenFileDialog, but is fully testable. The amount of decoupling you really need would be an implementation detail for you. For instance, in your case you may want a service that entirely hides the fact that you are using a dialog. Something along the lines of:
public interface IRemoveFiles
{
string[] GetFilesToRemove();
}
IRemoveFiles removeFiles = this.View.GetService<IRemoveFiles>();
string[] files = removeFiles.GetFilesToRemove();
You then have to ensure the View has an implementation for the IRemoveFiles service, for which there's several options available to you.
Onyx isn't ready for release yet, but the code is fully working and usable at the very least as a reference point. I hope to release stabilize the V1 interface very shortly, and will release as soon as we have decent documentation and samples.
I have run into this issue with MVVM as well. My first thought is to try to find a way to not use the dialog. Using WPF it is a lot easier to come up with a slicker way to do things than with a dialog.
When that is not possible, the best option seems to be to have the ViewModel call a Shared class to get the info from the user. The ViewModel should be completely unaware that a dialog is being shown.
So, as a simple example, if you needed the user to confirm a deletion, the ViewModel could call DialogHelper.ConfirmDeletion(), which would return a boolean of whether the user said yes or no. The actual showing of the dialog would be done in the Helper class.
For more advanced dialogs, returning lots of data, the helper method should return an object with all the info from the dialog in it.
I agree it is not the smoothest fit with the rest of MVVM, but I haven't found any better examples yet.
I'd have to say, Services are the way to go here.
The service interface provides a way of returning the data. Then the actual implementation of that service can show a dialog or whatever to get the information needed in the interface.
That way to test this you can mock the service interface in your tests, and the ViewModel is none the wiser. As far as the ViewModel is concerned, it asked a service for some information and it received what it needed.
What we are doing is somethng like that, what is described here:
http://www.codeproject.com/KB/WPF/DialogBehavior.aspx?msg=3439968#xx3439968xx
The ViewModel has a property that is called ConfirmDeletionViewModel. As soon as I set the Property the Behavior opens the dialog (modal or not) and uses the ConfirmDeletionViewModel. In addition I am passing a delegate that is executed when the user wants to close the dialog. This is basically a delegate that sets the ConfirmDeletionViewModel property to null.
For Dialogs of this sort. I define it as a nested class of the FindFilesCommand. If the basic dialog used among many commands I define it in a module accessible to those commands and have the command configure the dialog accordingly.
The command objects are enough to show how the dialog is interacting with the rest of the software. In my own software the Command objects reside in their own libraries so dialog are hidden from the rest of the system.
To do anything fancier is overkill in my opinion. In addition trying to keep it at the highest level often involving creating a lot of extra interfaces and registration methods. It is a lot of coding for little gain.
Like with any framework slavish devotion will lead you down some strange alleyways. You need to use judgment to see if there are other techniques to use when you get a bad code smell. Again in my opinion dialogs should be tightly bound and defined next to the command that use them. That way five years later I can come back to that section of the code and see everything that command is dealing with.
Again in the few instances that a dialog is useful to multiple commands I define it in a module common to all of them. However in my software maybe 1 out of 20 dialogs is like this. The main exception being the file open/save dialog. If a dialog is used by dozens of commands then I would go the full route of defining a interface, creating a form to implement that interface and registering that form.
If Localization for international use is important to your application you will need to make sure you account for that with this scheme as all the forms are not in one module.