I understood the basic priinciple of not calling the MessageBox in the ViewModel code or the Model code but instead use a callback of some kind, be it an interface or a func declaration that is added to the ViewModel upon construction.
So far, so good.
But the examples given only go so far that you press a button in the View and then the ViewModel raises the MessageBox via callback to confirm and then continues.
But what if the Model is doing tons of stuff first before realizing the need for a user feedback? Do I give the model also the callback function to work?
Does it have to be designed differently?
Any advice is appreciated. :-)
In my opinion, it shouldn't be a big issue to raise the callback from your model, but I guess this depends on your architecture and your personal preferences.
So if you really don't want to have any callbacks connected to the view in your model, you could let your mvvm (or your presentation/application layer) handle the control flow instead of letting the model do it.
You could implement your model methods more fine grained and let the application layer coordinate the operations of your model. In that way, whenever a model operation is completed and a user input is required, the mvvm layer could raise the callback.
Example:
// method of your view model / application layer
public void InteractiveProcessing()
{
// business logic is separated in smaller chunks
model.DoFirstPartOfOperation();
// check if model needs additional user input
if(model.NeedsInput)
// raise callback here, let user enter input etc...
// continue processing with user input
model.DoSecondPartOfOperation(userInput);
}
Of course this makes only sense if you could split up your business logic into smaller parts.
You expose a public event, and have the View (.xaml.cs) to listen to it on startup. The code is still going to run on the worker thread, but the backend logic will not hang during unit testing.
OK, I think I've figured it out.
In my model I've encapsulated every call to the file system in a self-written interface called IIOServices and all my UI calls in an interface called IUIServices.
The UIServices only use standard datatypes or self-defined enums and nothing from the System.Windows.Forms or System.Windows namespace.
Then the clients of the model are responsible for providing an implementation to access FileOpenDialogs and MessageBoxes and such in any way they please.
My sample code for this implementation (which is kept small for the learning experience) can be found here, if anyone's interested:
MVVM with MessageBoxes sample code
Related
I am looking for an easy approach to test a (medium size) WPF application. Sort of what you'd do with BDD, but without the fancy specflow scripts, and instead of invoking mouse clicks we just want to interact with the ViewModel layer.
I refactored the code slightly so that I can start the application easier from a unit test. This is what I have now:
[TestFixture, RequiresSTA]
public class StartAndInitializeTests
{
[Test]
public void StartAndInitializeSystemControl()
{
var systemControl = new SystemControl((string) "302");
// This line of code never gets executed because of App.Run() is not returning until
// the application stops.
ViewModelContext.MachineControllerViewModel.InitMachine();
}
}
Obviously the InitMachine method will never execute, because constructing SystemControl in the end results in the WPF app being started (App.Run()).
What is the best way around this? Handcraft some multi-threading framework which posts events to the UI thread and "mimics" user events? Or is there a somewhat proven framework that I should know about? Or should I have a completely different approach?
PS:
We are not looking for an approach with specflow, because we don't really need external stakeholders to write tests, so we can and will manage this in NUnit directly
We want to interact with ViewModels directly so that we don't have to bother with frameworks like White. Maybe we will go down that path in the future, but for starters we would like to keep it as simple as possible.
Many thanks in advance!
Generally you don't need to init the whole application when testing at a ViewModel level. You should be using dependency injection which means if you instantiate a ViewModel any of its dependency will get injected appropriately in its constructor. You can then perform your tests on the resulting ViewModel. You may want to hook into ViewModel OnChangeNotify events and your Model to perform validation for your tests.
A simple example may be a property modifier on your ViewModel that modifies a property in the Model. A example test may construct the ViewModel in question and hook into the Model underlying the ViewModel, modify the property on the ViewModel and check that the appropriate value is modified in the Model.
My specific issue is an attempt to execute the Telerik DataBoundListBox method StopPullToRefreshLoading(true) from my ViewModel. The difficulty is that I do not want to break MVVM convention by putting application logic in the code behind.
I'm relatively new to MVVM and I'm not sure what the proper convention is for interacting with methods on controls on the view. I've done numerous searches on the topic and I've yet to find a solution that I can apply to my situation. I suspect I've probably come across the answer but I'm not drawing the proper conclusions.
It seems like this would be a common situation with 3rd party controls but maybe I'm just not thinking about the problem in the proper way.
I'm building my first Windows 8 Phone app using MVVM Light.
A lot of people get very hung up thinking that when following MVVM you MUST NOT HAVE CODE IN THE CODE BEHIND!!! This simply isn't the case, a design pattern like MVVM is there to make the code more maintainable. If something relates directly to the UI only and doesn't care about information in the viewmodel class then by all means put it in the code behind. I had the same situation when I was using third partly controls, sometimes there is no other option that isn't as bad or worse than putting code in the code behind.
First I agree with Chris McCabe on this, design patterns are a guideline, a framework, a suggestion. They are not rules to live-or-die by. That being said, you should be able to join the two (VM/Telerik) without introducing 'real' business logic into the UI.
The first possibility is to use an event on the controller. The UI can subscribe to this event to forward the call to the Telerik control; however, the UI should not decide when it is called.
class MyModel {
public event EventHandler StopRefreshLoading;
}
class myForm : Form {
public myForm(MyModel data)
{
data.StopRefereshLoading += (o, e) => this.CustomControl.StopPullToRefreshLoading(true);
// ... etc
}
Frankly, I prefer using interfaces for this type of behavior. It's then easy for the controller to force implementations to update to a new contract requirement. The downside is that the interfaces can become too verbose in a complex UI making them difficult to write tests for.
interface IMyModelView {
void StopRefreshLoading();
}
class myForm : Form, IMyModelView {
void IMyModelView.StopRefreshLoading()
{
this.CustomControl.StopPullToRefreshLoading(true);
}
Either direction you go some violation of the UI design pattern is likely to occur; however, in the real world there are no points for strictly adhering to a specific pattern. The patterns are there as an aid to make the code more reliable, testable, flexible, whatever. Decide why you are using a pattern and you will be able to evaluate when can safely violate that pattern.
I have a form and a logic class. Based on user actions, the class generates a list of actions. These actions then need to be displayed as buttons on the form, so the user can select from them.
My initial solution was this:
public class Logic {
public List<string> GetActions() {
List<string> result = new List<string>();
// ...prepare list
return result;
}
}
public class FrmGUI : Form {
Logic logic = new Logic();
private void PopulateButtons() {
foreach(string action in logic.GetActions(){
//...create button
}
}
}
The GUI retrieves the list of strings from the Logic class and then uses that to populate a panel with buttons. Now supposedly this is bad OO practise because I'm exposing something about how Logic class behaves. There is an assumption here that the GetActions method will always exist and that the Logic class will always be able to return this list of strings.
Another solution is this:
public class Logic {
public void PopulateButtons(Panel panel, Action<object, EventArgs> eventHandler) {
// ...prepare list
// ...populate buttons
}
}
public class FrmGUI : Form {
Logic logic = new Logic();
private void PopulateButtons() {
logic.PopulateButtons(this.panel1, actionButtonClickHandler);
}
}
Now here the GUI class knows nothing about the logic class and only expects to get the buttons populated. On the other hand, the logic class is now involved in GUI stuff.
What is the correct way to handle such cases. Or is there a third implementation which is better.
I'd use the former patttern: The Logic-layer creates information, and UI-layer uses that information to create the UI.
That way, if you decide to re-skin the UI to use a drop-down list of items you only have to change the UI layer, not the logic.
It means that the UI layer has a minimal dependency on the types/data provided by the logic layer (as long as it doesn't know anything about how the logic is implemented, that is fine), but the logic layer has no idea whatsoever about what the UI implementation is - which is what you want (the lower level components in a system should not know anything about the higher level design, while the higher level components must necessarily have a basic understanding of the low-level components that they utilise).
It would be preferable that the application (or some other external entity) creates both the Logic and UI and links them together, rather than the UI itself creating the Logic - this will help the UI and logic to be much more loosely coupled.
I would recommend placing a layer of abstraction between your Logic and your FrmGUI.
For a simplistic example, let's say you have a login in you application. Define an interface for your logical screen. Note there is no mention here of what controls are used. The Logic classes never knows the UI class/form used.
interface ILoginScreen : IScreen
{
event EventHandler LoginInvoked;
event EventHandler CancelInvoked;
string User { get; set; }
string Password { get; set; }
}
In your LoginLogic class you have code like this:
void Start() // initial LoginLogic method
{
ILoginScreen loginScreen = uiFactory.CreateLoginScreen();
loginScreen.User = string.empty;
loginScreen.Password = string.empty;
loginScreen.LoginInvoked += new EventHandler(LoginScreen_LoginInvoked);
loginScreen.CancelInvoked += new EventHandler(LoginScreen_CancelInvoked);
loginScreen.Show();
}
void LoginScreen_LoginInvoked(s, e)
{
if (ValidateCredentials(loginScreen.User, loginScreen.Password))
{
// goto the next screen logic controller
}
}
In your form, you implement ILoginScreen and refresh the UI fields with data from teh USer and Password properties. Additionally, you raise the required Login and Cancel events based on the user feedback (button click, Escape keystroke, whatever).
While this is a simplistic example, I do a lot of Windows Mobile and Windows CE apps where it is very common to want to run the same application on vastly different form-factors OS variants and this approach lets you literally snap on new GUI form-factors. The heart of that usage is the UIFactory that is dynamically loaded to provide the appropriate UI implementation.
That Logic can report the actions it supports (1st pattern) looks fine to me (but the return type of GetActions really should be IEnumerable<string> instead of a list).
Not so good is that in your sample the form instantiates the Logic class directly. Typically, you'd create an interface or abstract base class for the different types of Logic classes that you might have, and have concrete implementations fill in the functionality. The form would then get the logic to use through some inversion-of-control mechanism.
correct????? Over the years lots of people have invested lots of time in trying standardise this approach and I'm afraid the answer may be deduced from the number of ui design patterns out there!
You may want to look at MVC, MVP, MVVM patterns, all of which are in vogue at the moment.
In general:
it is a good idea to try to split logic from presentation, so you're on the right lines. But remember that one of the consequences of this split is that it is better for your "logic" not to know anything about presentation (since you already have a class responsible for that).
So you might want to think about the concept of "buttons", and think (from your logic point of view), "don't I really mean commands?". They only really become buttons when you think of them in the context of a screen. But, say, a command to load the transactions on a particular bank account....you don't need a screen to conceptualise how this would work.
A good thing I find is to imagine that you're going to develop this app with both a forms front end and, say, a web front end which does exactly the same thing. Obviously these two apps would have a totally different presentation layer because of the fundamentally different technologies involved.
But because you don't want to write code twice you'll have a "logic" layer too, where you'll stuff as much common code as you can. For example, deciding whether a bank account is overdrawn - doesn't matter whether you're web or win, overdrawn is still overdrawn. And conversely, any place where you'd end up writing different code between web and win belongs into your "presentation" layer. For example, displaying an overdrawn balance in red.
Food for thought.
the first one is better, because your interface between GUI and logic is just a list of string.
After, it all depends on the way you're calling actions on your logic class from your button.
If you have a generic method taking the action string, it's fine. If you need to call different methods on your logic class depending on the action string, you'll need a mapping in the GUI class to map action string and method call. you could also import this "action string - mapping method" from your logic class to keep things separated.
My opinion is, it depends on the reason for creating something like a logic tier and a GUI tier. I think the most common reason is to reuse the logic, e.g. to use it for a WPF and a web GUI, or the data has to be processed before sending it to the GUI. Your first example fits the mentioned pattern. In your second example the logic seems not to be reuseable, because its gui specific.
However, in the real world there it right or wrong answer. The architecture should fit your needs and make your project maintainable(e.g. by reduce redundant code).
In your case the question is: How often do you need these functions and where/when do you need them?
I have a big winform with 6 tabs on it, filled with controls. The first tab is the main tab, the other 5 tabs are part of the main tab. In database terms, the other 5 tabs have a reference to the main tab.
As you can imagine, my form is becoming very large and hard to maintain. So my question is, how do you deal with large UI's? How do you handle that?
Consider your aim before you start. You want to aim for SOLID principles, in my opinion. This means, amongst other things, that a class/method should have a single responsibility. In your case, your form code is probably coordinating UI stuff and business rules/domain methods.
Breaking down into usercontrols is a good way to start. Perhaps in your case each tab would have only one usercontrol, for example. You can then keep the actual form code very simple, loading and populating usercontrols. You should have a Command Processor implementation that these usercontrols can publish/subscribe to, to enable inter-view conversations.
Also, research UI design patterns. M-V-C is very popular and well-established, though difficult to implement in stateful desktop-based apps. This has given rise to M-V-P/passive view and M-V-VM patterns. Personally I go for MVVM but you can end up building a lot of "framework code" when implementing in WinForms if you're not careful - keep it simple.
Also, start thinking in terms of "Tasks" or "Actions" therefore building a task-based UI rather than having what amounts to a create/read/update/delete (CRUD) UI. Consider the object bound to the first tab to be an aggregate root, and have buttons/toolbars/linklabels that users can click on to perform certain tasks. When they do so, they may be navigated to a totally different page that aggregates only the specific fields required to do that job, therefore removing the complexity.
Command Processor
The Command Processor pattern is basically a synchronous publisher/consumer pattern for user-initiated events. A basic (and fairly naive) example is included below.
Essentially what you're trying to achieve with this pattern is to move the actual handling of events from the form itself. The form might still deal with UI issues such as hiding/[dis/en]abling controls, animation, etc, but a clean separation of concerns for the real business logic is what you're aiming for. If you have a rich domain model, the "command handlers" will essentially coordinate calls to methods on the domain model. The command processor itself gives you a useful place to wrap handler methods in transactions or provide AOP-style stuff like auditing and logging, too.
public class UserForm : Form
{
private ICommandProcessor _commandProcessor;
public UserForm()
{
// Poor-man's IoC, try to avoid this by using an IoC container
_commandProcessor = new CommandProcessor();
}
private void saveUserButton_Click(object sender, EventArgs e)
{
_commandProcessor.Process(new SaveUserCommand(GetUserFromFormFields()));
}
}
public class CommandProcessor : ICommandProcessor
{
public void Process(object command)
{
ICommandHandler[] handlers = FindHandlers(command);
foreach (ICommandHandler handler in handlers)
{
handler.Handle(command);
}
}
}
The key to handle a large UI is a clean separation of concerns and encapsulation. In my experience, it's best to keep the UI free of data and functionality as much as possible: The Model-View-Controller is a famous (but rather hard to apply) pattern to achieve this.
As the UI tends to get cluttered by the UI code alone it's best to separate all other code from the UI and delegate all things that don't concern the UI directly to other classes (e.g. delegating the handling of user input to controller classes). You could apply this by having a controller class for each tab, but this depends on how complicated each tab is. Maybe it's better to break a single tab down into several controller classes themself and compose them in a single controller class for the tab for easier handling.
I found a variation of the MVC pattern to be useful: The passive view. In this pattern, the view holds nothing more than the hierarchy and state of the UI components. Everything else is delegated to and controlled by controller classes which figure out what to do on user input.
Of course, it also helps to break the UI itself down into well organized and encapusalted components itself.
I would suggest you to read about the CAB ( Composite UI Application Block ) from Microsoft practice and patterns, which features the following patterns : Command Pattern, Strategy Pattern, MVP Pattern ... etc.
Microsoft Practice and patterns
Composite UI Application Block
Does anyone have any hard and fast rules about what kind of code the form object should handle as opposed to letting the object itself handle it? For example, if there is a race, should the object that is racing say, horses, handle the race as part of being a horse, or is it better to place that inside the form object? I guess what I'm asking is how one decides what goes into an object like a horse as say a method, and what goes into a form object instead of a horse. Are there any rules you use to figure out where code is best abstracted in this case?
This is called "separation of concerns". Let the form handle the display and user interaction. Let the Racer handle racing.
I try to develop my software so that core functionality that is not UI dependent is abstracted into classes that bear responsibility for their tasks.
Try to think:
How could I write this so I could have both a GUI interface and a console interface without duplicating any code.
The UI should only handle visuals & user interaction. Everything else should be organized based on its role.
Not sure there is absolutely a right answer here. But agreed with John Saunders. A "Form's" job is primarily responsible to display data to the user and accept data input. The closer you keep it to that, and that alone. Think about when there's another place for this type of data to be used, if the code is elsewhere, it can be reused.
Have a "Business Object" or a "Facade" handle the logic of the race, and the form to display it.
Try to represent things the way they are in the real world. Anything that describes the properties or actions of a horse, belongs in a horse object. Anything that describes the properties or actions of a race (including, perhaps, a collection of horse objects), belongs in a race object. A form is not a real world object, but just a gadget for displaying information from horses/races/whatever. So don't store anything with the form except as needed to present the real data on the screen.
Since the form is part of the UI I would apply my UI hard and fast rule:
UI = formating, sorting and displaying data plus accepting and verifying input