I am in the process of recreating a Win32 (Delphi 5) screen using WPF in C# with the MVVM pattern. The purpose is to create a demo that I can use to push my company to make the move from Delphi 5 to C#. In this demo I want to do things the "right" way so we have a good example to start with. With that in mind, I am trying to adhere to MVVM as strictly as possible which is where I am currently running in to a problem.
In the original program/screen we have lookup dialogs that we can attach to edit boxes and grid cells. The way it works is that the lookup dialog is an implementation of a specific search (i.e. Customer lookup). When you attach the lookup dialog to a control, it listens to the key press events for the control. It has a progressive search feature so that when you start typing, if it can find results that start with what you are typing it will insert the first result in control you attached it to. While doing this it keeps the cursor where you were typing and highlights the part of the data that you typed in so that if you keep typing it can narrow down the results to find the more specific answer you were looking for. Where the dialog part comes in to play is when you hit the ellipse button next to the control or if you type in something that it couldn't find while doing the progressive search. In either of those cases it will bring up the lookup gui which will show you all the possible results, provide filters to help you narrow your search down etc. This gui is visually attached to the control you assigned it to. It always pops up right under the cell or edit box etc that you assigned it to.
So this lookup dialog is throwing me off when it comes to trying to figure out how to implement it using MVVM. So far my code mostly pure as far as MVVM goes. The only code in the Views code behind is the one line creating the ViewModel and assigning it to its DataContext. The ViewModel makes no references to the view. But with this lookup dialog the lines seem a little blurred to me. I envision the lookup having it's own ViewModel. When you lookup something, say an Item to be put in a Sales Order, we may want to get information like the Item's price from the lookup so that it can be copied in to the Sales Order record. So to do that the main ViewModel for the screen needs to know about the lookup's ViewModel. The View for the main screen needs to know about the View for the lookup too though because it has to be able to "attach" the lookup to a gui control so it can listen to key press events and know where to visually popup when it needs to be shown. I'm not sure if the code determining the visual position of the lookup should reside in the lookups ViewModel which would break the MVVM concept totally or maybe in the lookup's view's code behind which would muddy the purity of the view a bit since now the View isn't just the XAML.
The original lookup, after being created, would be given a reference to the control that it should attach to. It would then attach functions within its object to the key press and button click events (our edit boxes can have buttons built-in). When it was told to popup, it would figure out the current position of the control it is attached to so that it could figure out where to put itself. In the case of attaching it to a grid, it was actually attached to the column of the grid because there is only one instance of the lookup, and it would figure out the current position of the cell in the grid it is supposed to be popping up under.
What is the best way to do this while still staying in the realm of MVVM. I really would like to stay as "pure" as possible so I can come back later and add integration and possibly unit tests for the ViewModels in the program and these should be ViewModels that are "headless" (no View).
To make it easier to understand what I am trying to achieve I have included a picture of the screen I am recreating for my demo with the lookup shown.
Related
I have a report part in my WPF application which contains some different WPF Pages. I need my report pages to be edittable by user. Each report page contains different Textbox and RichTextBox controls.
Whenever some control's value is changed, if I press ctrl+z and ctrl+y on my keyboard, Undo and Redo will happen only if the control is focused.
Is there any way to extend the functionality of these key combinations to execute Undo and Redo process on all of existing controls in the page without needing to focus on them?
If you lock your effects under a command pattern you can handle the undo/redo events yourself. As long as the wpf controls involved are bound to the data that is done/undone/redone. That makes it possible.
see Undo/Redo Implementation For Multiple Variables
You could use the brute force approach.
Assuming you're using MVVM ( if you're not then you should learn and use it ).
Handle propertchanged in the viewmodel(s) and persist before and after by serialising the entire viewmodel to a collection of viewmodels. One for each state. You then iterate backwards through that collection to go back and forwards to re-apply.
This is relatively easy to implement but the downside is the potential to lose changes between redo.
You could improve on that by adding a bit more sophistication. Retaining a property name, old and new value per propertychange.
I want to create a kiosk mode application using WPF. I want to use a single window because the user should not be able to exit this fullscreen application.
The application should guide the user trough a process. When the user proceeds trough the process, the screen should constantly change and show him the next step.
Usually I just create a single window and use a "state machine" to switch UserControls containing the information for the current step. Is there a better way to achieve this functionality? Maybe I would get a better result using multiple windows or Pages (never used them).
The reason why I am asking is that in future I want to have a simple, clean way of switching the content inside a single window. i.e. I am planning to implement some sort of animation when switching content (like sliding to the next / previous step). I don't want to put more effort into my current approach if it isn't the most flexible and clean one.
Any ideas?
PS: This is about desktop applications. Today I come from the Winforms environment and am experimenting with WPF.
There's a few ways you can achieve this.
First would be to use a Page based application, this will allow you to use a single window. Here is a pretty interesting tutorial
A bonus of using this approach is that navigation between pages is built in.
Your requirements are that you need to use animation for transitioning between pages, as far as I'm aware, using a Page based application cannot achieve this (I may be wrong). So your other option would be to use a UserControl MVVM approach.
This probably won't make a lot of sense now, but here goes:
You can use a single master view model which will hold multiple child view models, each of these could have a visibility property which dictates the visibility of the associated view. The master view model would simply be responsible for displaying the appropriate view model depending on where the user currently is in the application.
Using some clever XAML, you can create storyboards (animations) when the view becomes visible, which will allow you to achieve the crazy awesome animations that you require.
Anyway, that probably didn't make any sense, so here's a tutorial to get you started with MVVM.
I want to create a set of controls in the designer and then replicate it over and over again. Here's a picture to help visualize what I'm describing:
Currently I program the position of each control to fit properly in the panel. Doing it this way is tedious and I have to run the program each time I make a change to make sure everything lines up the way I like it. This is the fourth iteration of this panel and I'm getting ready to do at least two more designs for different customers who want slightly different ways of displaying the same data.
Is there a way to draw the panel and its controls in the designer, the programmatically replicate the entire set of controls, and bind different data to each of them?
If you want to allow customer to move these controls around, you need:
Create persistence storage. Basically, your control needs to build itself from some sort of file or better - database, where all the positions and other properties will be set, saved, etc.
Develop a "design mode" for customer. Customer will click button "Design" and be able to move controls around, re-size them, etc. For you, in design mode you want to make controls druggable and also, you need to devise a way for resizing them too. Then customer clicks "Save" and control data should save into the persistence storage.
Now, if you ok with reimplementing multipple looks for customers and want to do it quickly - create a UserControl, place TableLayoutPanel on it and then use series of TableLayoutPanel's to give any look to your control. This is rather fast way. And if I only needed to do it 10 times, I would just create a control factory, and add every new implementation into it. Let customer pick out of existing implementations. Because creating designer will be rather involved effort.
I would like to write a program that uses several tabs, each showing a data grid. The data of all the grids is stored in a single data source. Each tab should look identical except for the number of colums/rows and the values of course.
So I am now trying to put the grid view into a user control and create a .dll. If a tab is added I put the user control into it - this works already. The grid works in virtual mode and if a new tab/grid is created it calls the event to load the data into the grid.
Now I have the problem that the grid and the LoadData event are in the user control while the data source is in my main program. So in the user control the data source is undefined. I thought that this would be ok because you do not run the user control alone and once it is used in the main program the data source should be available to the LoadData event. However, it does not seems to be possible to generate the .dll while the data source is unknown.
On the other hand I do not want to put the data source into the user control because then it is dublicated every time a new tab is created.
I hope you can give me a hint what is the best way to implement it.
thank you very much!
I don't know what answer (how detailed) you expect, but I think this is a very good example to:
reuse one control
use MVVM architecture pattern
I would try to seperate class which would execute logic responsible for creating ViewModel. Control (grid in your purpose) would be always binded to this ViewModel, and this Control would be reuse in different Views. Depend on where it would be placed you can add some additional features if it is necessary (Decorator design pattern). If you expected more detailed (not conceptual) solution than sorry.
I am looking into developing a GUI that will switch the controls based on the value of the selected combo box item.
I have tried adding a different canvas or grid to the gui designer in visual studio but it comes hard to manage as everything overlaps each other in the designer and is hard to know what's what.
Is there an easy way that I can do this, is there a particular control that makes this easy to achieve. I don't really want code the gui in c# and not use xaml.
What I was hoping to do is that all the controls are in there own panel and when the combo box value is changed one panel is removed or hidden and the other is shown.
How can something like this be achieved.
Thanks for any help you can provide
You could implement each different "mode" as a separate UserControl.
Then have a shell with the combobox, where the combobox OnChange will swap out what UserControl is plugged into the shell.
Any other totally common components such as OK/cancel buttons could be part of the shell.
A completely alternative implementation to consider is a tabbed approach, but that probably only flies if it makes sense for the user to act on several of them.
What will you do if the user selects A in the combo, makes changes in UserControlForA, and then selects B in the combo? Could be an annoying corner case, and if this is production code the sort of thing that you'll get future user requests to change how it works.
If you're sure of the design go for it. If not, I'd play around with a few apps and try to find a nice example of the same sort of thing, and consider how they approached it.
But techwise I think a UserControl is what you're describing.
(Edit: crud just saw the xaml/wpf in the question, not sure this is correct in that context, clueless there)
You can use DataTemplate for each different mode.See Different item template for each item in a WPF List for more information.