Load view on double-click of row - have bindings working, and event being fired on click, but how do I actually get the view to pop up? - silverlight

I have a view in Silverlight which contains a telerik:RadGridView with a number of columns.
I have it wired up so that when the user double-clicks on one of these columns, an event is fired. However, I don't know what to put in the event handler.
private void RowClicked()
{
//What goes here?
}
All I wish to do is load a popup view over my current view, with a close button so that the user can return to the previous view. A simple idea that is surely done a billion times everywhere, but I cannot figure it out or find examples of this anywhere.
Can anyone help?
Thanks very much.

You can set a previous view as input parameter to "RowClicked()" method. You will have a reference on previous view in current method. You can use it via Commands (bind a command and a command parameter to some action/event).
I have an one more idea (if you have a lot of views): you can create a navigation service. It is an interface, which contains events and methods. You should use events for navigation and methods - for sending needed data. Everyone of view should implement this interface. Needed event will be raised under view via some action (for example: button click). As for events: you can create a custom event handler, there you will set a sender instance and needed parameters. You should create a Navigation manager, there you should create a property for selected view and subscribe on everyone event. If user want navigate to another view, he will do some action and system will raise an event. You can create a custom container for created views. This container you can use for getting created instance of needed view. As you know, creating a new instance is heavy for system: need a some time and system resources. Will be easy to get a created instance of view instead a create a new. For setting default data or refreshing a binding you can user a custom method, contractor for which will be added to navigation interface.
It is a simple idea, which I used in one project. As for others samples: You can find another navigation frameworks and custom classes in internet. But, process of creating an own system will give you a level up in your work experience.

Related

Creating a Visual Studio style errors tool window with jump to error functionality

I'm using Caliburn Micro to create a Visual Studio style interface for my application.
The user could have multiple errors in multiple windows which are all shown on an 'errors' view which is docked at the bottom of my application. I've managed to implement a nice notification mechanism so that when changes are made to any document, the errors VM is notified and queries the source object.
I'm having trouble, however, in figuring out how to get a double-click to navigate to the source of the error.
Imagine I have bound 'description' to a textbox on my document view and this provides a 'description is required' validation message. Double clicking the message should navigate the user to the document in question and focus on the textbox.
The validation objects that provide the messages already contain a reference to the viewmodel (as an IViewAware interface) which allows me to call GetView() to get a reference to the view. I've tried using this approach to enumerate the bindings on my view and find the controls that are bound to a particular property, though this is very slow and more of a brute force - pot luck approach
Does anyone have any recommendations on approaches to this problem? My only other thought is to pass responsibility of the 'focus' action to the view itself and have that decide how to handle a request for navigation to a certain property - maybe using attached properties to identify particular controls by a unique property identifier. The application could cache this list in a dictionary to make things quicker (all the processing done up front as the app is loading)
I assume Visual Studio implements this quite easily for the standard code editor window, since it just needs a line number to jump to the right place..
Ok so after a couple of hours messing about with this I've come to a solution which seems to work ok. I've implemented an interface class for my views which allows them to navigate.
The basic setup is:
ErrorsViewModel - receives notifications that a business object needs requerying for errors and manages the list of errors and when it needs to query (so that any work can be done on a background thread to prevent locking the UI)
WorkspaceViewModel - the main workspace VM that hosts the tool panes and documents
ICanNavigate - interface that the views will impelement to decide how to handle navigation arguments
NavigationEventMessage - the message that is sent to the event aggregator to provide a navigation notification and arguments
The ErrorsViewModel receives an event message from another VM via the event aggregator and eventually queries the object (when it can). Once the errors are gathered, it shows the items in the view (in a grid control at the moment).
When the user double clicks on a row a NavigationEventMessage is dispatched which contains some arguments such as the view that dispatched it and the target business object etc. It is handled by..
1) The WorkspaceViewModels view. This allows it to bring the correct document into activation by looking at the DataContext of each object and checking if it matches the view passed in the message
2) The target documents view, the view decides what to highlight/show/seek to based on the arguments sent in the message
This seemed to be the most logical way to separate the VM from the View as the ViewModels still have no coupling with the views. The view just implements the interface, and the VM calls it if it's there and passes in the args.

Triggering a command in the view model based on an action in the view

I am working with the Infragistics XamDatagrid. When an event takes place in the view (new record updated), I would like to call a method in the view model. I can't just listen to the CollectionChanged event of the source in the VM because that event gets triggered once the user begins editing the new row in the grid. The RecordUpdating event gets called when the user finished the edits.
What I am doing now is accessing the DataContext directly and calling the method. The problem is that there is nowhere I can find to attach a Command to the gird that would tigger on the event I am interested, nothing like the Command of a Button.
Generally, what is the best way to call into a VM from a view when there is no Command parameter I can set in the view?
Code-behind glue is fine in most cases, but if you find yourself gluing the same type of thing repeatedly, you can look into Attached Behaviors. Here's one old-school approach the introduces the concepts, but doesn't use the new Behavior class: http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx
Here is an example using the new Behavior class, including a demonstration of how it integrates with Blend: http://geekswithblogs.net/lbugnion/archive/2009/04/05/using-a-behavior-to-magnify-your-wpf-applications.aspx

WPF Calling function in Page from "Master" Window

I have a button in a Window that needs to call a function in pages contained within a frame. The page inside the frame will change based on a navigation contained in the main Window, so I will know the current Page within the frame.
Can someone help with how to call function in frame pages?
If you wish to approach this from an MVVM perspective, you'll want to make sure you're not working with the actual view here, but the ViewModel abstraction of it. In that case, your parent Window is probably backed by a ViewModel that contains some sort of a collection that backs your pages in the frame/tab control/container of choice. In that case, the button should link to a command on your Window-backing ViewModel and use the selected item in the collection to access the function. If you do not have a direct reference in this fashion (for example loading in from another module or something for frame contents) you can also use EventAggregator from the Prism/CAL libraries and publish an event when the window button is pressed and set up your pages to receive that event and handle the call there. EventAggregator can be a slick way to handle cross-module logic in a clean way.

Main page xaml to manage user control events

I need an elegant solution (I am working on silverlight 4.0) to solve this simple problem(?) using the MVVM pattern:
My mainpage xaml has my two custom user controls like this (say):
<uc:MyCustomUC1>
<uc:MyCustomUC2>
Each one has its own view model and both these user controls are independent of each other.
When an asynchronous operation in MyCustomUC1 has completed, I want an ICommand in MyCustomUC2's viewmodel to be invoked thus refreshing data in MyCustomUC2. I want this done by the parent page and all in xaml.
Exposing dependency properties, event handlers etc in the user controls...anything is ok since I own the user control ...whatever makes sense.
Any ideas ?
Use Mvvm Lights messenger, you can register a listener in MyCustomUC2's viewmodel to refresh. Then in MyCustomUC1's async call back, send the message to refresh.
You could use a PropertyObserver, which I believe you can find info on here:
Property Observer.
It'll allow you to check when something has changed in one ViewModel and then take the appropriate action in another. I've used this quite a bit recently in a project and it has worked pretty well.
Apologies if I've picked up the question incorrectly.

How do I get the NavigationService without being a Page?

This seems to be a really naive question, but how on earth does one get the NavigationService from outside of a page, like say perhaps a view model? Everybody says that navigation should occur at the view, but I keep thinking, this is not a web page, its an application. The view model and business logic should control application flow, not the view. Is this in fact naive?
As far as I understand it, operations involving the View, i.e. UI, should be done by the View exclusively. When working with MVVM, the UI should not be controlled by the ViewModel or BusinessLogic directly (since they are not supposed to know anything about the concrete implementation of the View) but work with Messages.
That means, if we want to open an Editor window from the ViewModel we send a Message from the ViewModel that we want to open it and receive it in the View and open the window there. The same is valid for Navigating through different pages, where you would receive the Message in the MainPage (or whatever holds you pages that you want to navigate through) and handle everything there.
An alternative to that would be using a DialogService or something like that, which handles opening windows in a central place. However, since the NavigationService is a property of the Page class, we need to handle the message in the Page.
Example code, using the MVVM Light Toolkit: (not tested, partly taken from Shawn Wildermuth's RiaXBoxGames example):
ViewModel (e.g., put that in a Command for a Button):
Messenger.Default.Send<bool>(true, "GoToNextPage");
View (e.g. put that in a Constructor):
Messenger.Default.Register<bool>(this, "GoToNextPage", ignore =>
{
// your code to go to next page
});
another option is to create an event on ViewModel, fire this event when Command occurs and subscribe View to this event. Inside EventArgs you can carry which page to navigate to etc. I think simple and testable solution.
Robert
I just pass a reference to the Frame when I create the View-Model.

Resources