Queue of commands - c#

So I have a database (sql) management program I have been working on, dealing with items my company sells. For the main part of the program the item information is updated as the user goes through using some custom controls. That all works fine. But now I am on to the higher level section of the program that is adding/deleting/copying items. This cannot be "update on the fly", like editing item information, as it would be too easy to screw things up very badly. So I basically want to set up a file-> save type of deal for them here. How I see this working is creating all of the sql commands in a list and then running them all when saving.
The functions available here would be adding a new item, deleting an item, copying from another item, and renaming.
So it would be a list like:
insert...
update...
update...
delete...
update...
etc.
It would run through and execute all of the commands. The problem I am having is I already have a class that has methods to handle all of these functions. I can't think of a way to call all of those methods in a queue, and rewriting all the sql statements in another class seems stupid to me. Is there a way that I can remember a list of something like:
item.Rename()
item.ChangeSize()
item.Delete()
I feel like I'm overthinking this... or maybe underthinking... I don't know.

What you are looking for is a Command Pattern.
The basic idea is that you have an ICommand Interface which has a method Execute().
Then you implement multiple ConcreteCommand, e.g. a RenameCommand with a parameterized constructor or a property NewName.
Dont't forget to handle exceptions accordingly and maybe implement an Undo-Method as well, if these could occur. I don't know enough about your application to make assumptions here.
public interface ICommand
{
void Execute();
}
public class RenameCommand : ICommand
{
private string newName;
public RenameCommand(string newName)
{
this.newName = newName;
}
void ICommand.Execute()
{
item.rename(newName);
}
}

Related

How to "refresh" my ViewModels after database changes have been done in another ViewModel?

I'm currently writing a rather small desktop application using the MVVM Approach. It also utilizes Entity Framework 6 for the database access. Right now, my top-level ViewModel instantiates the 'smaller' ones, and passes them the DbContext I'm using. The smaller ViewModels I use correspond to UserControls sitting in a separate TabItem each. But if I change something in the database in one tab and switch the tab afterwards, the UI isn't keeping up, logically, since there is no OnPropertyChanged("SomeObservableCollection") Happening.
I thought about just "refreshing everything inside" when a TabItem becomes active, but on one hand, I don't know how to do this (it would basically be doing OnPropertyChanged(..) for every UI-relevant property, right?), and on the other hand, it does seem neither elegant nor 'correct'.
What should I do about this? And is using one global DbContext even good practice? I read about short-lived DbContext instances being better, but I also found the opposite statement regarding desktop applications...
How do you handle this scenario? It can't be that rare actually, can it? Thanks!
You have to look at using a Messenger (MvvMLight) or EventAggregator (Caliburn.Micro).
So when your context has changed you pass the message about it and update your SomeObservableCollection so OnPropertyChanged("SomeObservableCollection") will be raised.
Might Help . I have done this in small project . any better solutions are welcomed.
**Viewmodel 1 Where changes occurs**
//database call
string result = _dataService.Insert(data);
if(result=="Success")
{
//notify viewmodels using default messenger instance
MessengerInstance.Send(new NotificationMessage("notifycollection"));
}
Viewmodel 2 where we receive notification
public AssignTimeSlotViewModel(IDataService dataService)
{
// registering the notification
MessengerInstance.Register<NotificationMessage>(this, receiveNotification);
}
#region Messenger - receivers
private void receiveNotification(NotificationMessage msg)
{
if (msg.Notification == "notifycollection")
{
/// Call Database to keep collection updated.
// raise propety changed event if neccessary.
// Do Something
}
}
#endregion
Thats not an easy subject at all.
If you handle with a small amount of data and performance is not a problem for you, you could update your bindings every time the view gets loaded. Here you can see how to accomplish that.
A Problem if you do that is, that you have to do some extra logic for saving last selected items and reselect them after the view gets loaded.
Using a messenger could be an option too. But in my experience the messenger could make thinks messy if it is not implemented correctly. For example please dont use some magic strings as messeages.

Managing prerequisites with MEF and Caliburn Micro

Lets say I have a component with a number of smaller components which check prerequisites before the first one will be initialized. They are not dependent on one another so I don't care about order and would like them to run simultaneously. I am using MEF and Caliburn.Micro for presentation.
I thought about this setup:
class Big
{
[ImportMany]
public IEnumerable<IBigPrerequisite> Prerequisites {get; set;}
public void Initialize(){...}
}
and
interface IBigPrerequisite
{
public bool IsBusy {...}
public bool Allow {...}
public void StartChecking();
}
Now what I would like to accomplish with this is that the classes implementing IBigPrerequisite can open up a window (for example "File X was not found - this could lead to errors. Continue?") - this should be possible.
But I would only want one window to be visible at a time. How would I accomplish that besides just going synchronously?
EDIT - since the question seemed too vague
I need these Actions to run specifically before Big will be activated. Let's say we switch up the activation logic to something like this:
Big big; //we got this through Importing somewhere in composition
var allow = true;
var count = 0;
if(!pre.Any()) //no prerequisites, show window immediately
windowManager.ShowWindow(big)
foreach(var pre in big.Prerequisities)
{
pre.PropertyChanged += (s, args) =>
{
if(args.PropertyName == "IsBusy" && !pre.IsBusy) // if a prerequisite finished it's check
{
allow = allow && pre.Allow; //if one prerequisite says nay we could just return, actually...
count++;
if(count == big.Prerequisites.Count() && allow)
windowManager.ShowWindow(big);
}
}
pre.StartChecking();
}
Now, I explicitly want the classes implementing IBigPrerequisite to be able to open a window, but in case all prerequisites are met (no user interaction required) no window should be showing. I do not wish to open up a window for every class here.
I am looking for a way to, say, give the IBigPrerequisite (which should probably be called IPrerequisiteViewModel anyways) a property like bool RequestsWindow {get;} and have the View only created when a) the viewmodel requests it and b) no other prerequisite window is open at the time.
Note: the code here is for illustration only as I am not sure how to implement this behaviour yet. I am not experienced with these frameworks (and concepts) so if this question seems silly please bear with me.
You are mixing concepts here.
Active view management in Caliburn.Micro is handled by the Conductor class. A Conductor-derived ViewModel can display a large number of Screen-derived ViewModels (or other Conductors). Available items are stored in the Items property.
You can find a much better description at "Screens, Conductors and Composition"
MEF has nothing to do with the Conductors and the composition mechanism, although it can be used to pass a list of items to a conductor. You can define an [ImportMany] constructor parameter or public property that receives the Screens to display during initializations and store them in the conductor's Items property.
Using a constructor parameter is more elegant, as you won't have to copy the items from your property's setter to the Items property.
Finally, you shouldn't display messages when creating your views and viewmodels. This is something that should be left for a later step, eg. during the Activate method. The Conductors and MEF get the parts together and build the UI. Executing actions and talking to the user should be done only after the composition step has finished.
I am going to answer this question myself detailing how I ended up solving this.
I made a LoaderViewModel : Conductor<PropertyChangedBase>.Collection.OneActive, IChild<Shell> and gave it a Queue<PropertyChangedBase>.
It has Show/HideWindow methods by traversing the Parent-Properties until it arrives at the Window-Level.
It has Queue and Dequeue methods. Queue is used when PropertyChanged is fired on a RequestsView-Property and calls Dequeue if there's either no ActiveItem or the ActiveItem is not marked as busy. Dequeue will activate a new item if there is one in the queue and then call ShowWindow, if there is no item it will call HideWindow instead.
The initial HideWindow is done in the ViewAttached-Event since if the window is hidden, CM seems to have some strange behaviour. Here, the parallel checking of the prerequisites is started and an event-handler registered similar to the one in the first post.
Sorry for being verbose, but the code has gotten a bit lengthy. If someone wants me to post it up write a comment.

ViewModels opening dialogue

Is anything really wrong with a ViewModel opening additonal dialogues? Lets say I have a MainView and a MainViewModel. The MainViewModel is the datacontext for the MainView and does not, in fact, know or have any dependency on the mainview itself.
However, there are cases when the main view need to open dialogues that will affect the ViewModel data. For example, I may want show a dialogue and diplay some items to allow the users to select from. So, what I have settled on is this:
In my ViewModel, I have the following methods: AddItem, EditItem, and DeleteItem. However, in order to supply the items to add or edit, I need to present a list in some dialogue for the user to to choose from. Right now I have the ViewModel doing this only because I don't want to implement additional levels of abstraction for such simple tasks. Having the ViewModel do this means it can provide the list to be displayed to the user and, when the user finishes editing or selecting, it can easily update its member collections/properties.
Should I be shot for settling with this approach?
Shot? No. But there are good reasons for not doing this.
First, it kills testability of your ViewModel, as there's now a visual component in place. When you try to write automated unit tests against it, you'll still have to interact with it. You could mock it out, but it becomes more difficult to do so when you're calling UI methods.
Second, your viewmodel shouldn't care about what gets displayed. There's a real "separation of concern" issue when you start combining these things.
Third, it just has a "code smell."
There are a few things you can do to circumvent this issue. The first thing I would suggest is Don't use dialogs. Dialogs have their place, but programmers tend to overuse them. Rethink your design, and try to figure out how you can get the job done without interrupting the user.
Second, consider using a messaging framework to send messages between your viewmodel and view to do the navigation to the dialogs (if you absolutely have to use them). Messages are very easy to mock out and/or write unit tests around.
the easy way to do this: use a dialogservice - easy to use, easy to unittest!
see this.
I don't see any problems with ViewModels communicating with each other. The problem is if they start accessing the Views or other Dialogs since that will affect the systems testability.
If you really want a more loosely coupled system you could use some sort of messaging system for communication, but I doubt you need that here :-)
I always use a Seelctor service(just a basic dialog service) to do this - it's testable and mockable and keeps the code very SOLID.
class ViewModel
{
public ICommand ShowListSelectorForCounterparties { get; set; }
public IListSelectorService ListSelector { get; set; }
public void OnExecuteShowCounterpartySelector()
{
this.Counterparty = this.ListSelector.Select<Counterparty>();
}
}
where IListSelectorService can, at runtime, instantiate your dialog, present your list and return the selected item. The main good thing about running it this way is that your unit tests can mock the IListSelectorService.
I'm not sure if you are still looking for any help, but the approach that I have taken when it comes to dialogs is to have the view model raise an event that the view can then handle. The view can now do whatever it wants to get the data to the view model, so you can disply the dialog in the view without a problem. You pass the response from the dialog to the EventArgs of your event so that the view model has the data it is looking for in order to proceed.
For example:
Public Class View
Private WithEvents _VM AS new ViewModel()
Private Sub _VM_AddingItem(Sender AS Object, E AS ViewModel.ItemEventArgs)
Dim Dialog As new SomeDialog()
If Dialog.ShowDialog then
E.Item = Dialog.Item
Else
E.Cancel = True
End If
End Sub
End Class
Public Class ViewModel
Public Sub AddItem(Item AS Object)
Do Some Work here
End Sub
Private Sub _AddItem()
Dim Args AS New ItemEventArgs()
OnAddingItem(Args)
If not Args.Cancel Then AddItem(Args.Item)
End Sub
Protected Sub OnAddingItem()
RaiseEvent AddingItem(me, ItemEventArgs)
End Sub
Public Event AddingItem(Sender AS Object, E As ItemEventArgs)
Public Class ItemEventArgs
Public Property Item AS Object
Public Property Cancel AS Boolean = false
End Class
End Class
Then just wire up your command to the private _AddItem method which just raises the event to collect the necessary data for the AddItem method. I hope this helps :)

Adding functionality to an Entity/Component System

I'm attempting to write my own Entity/Component System from scratch in C# and I'm stuck on where/how to implement some functionality.
Edit: I figured out how where I'm going to add functions like Move() and Jump().
public static class Actions
{
public static void MoveUp(EntityManager entityManager, int EGUID) {}
public static void MoveDown(EntityManager entityManage, int EGUID {}
}
I can add them to a collection like so:
KeyboardController kbController = entityManager.GetComponent<KeyboardController(1);
kbController.KeyBindings.Add(Keys.Right, new Dictionary<KeyStateES, Action<EntityManager, int>());
kbController.KeyBindings[Keys.Right].Add(KeyStateES.Held, Actions.MoveUp);
And now I'm able to move the Entity around quite easily with key bindings. However, it's still not quite ideal because:
I can't bind more than one Method to a Key.
I'm forced to pass the Method Arguments in the InputManager class.
This is a problem because sometimes I'll want a key to perform multiple unrelated tasks and because it seems really silly for my InputManager to be the one passing the arguments for the methods. Ideally, I would like it so that a KeyDown, KeyHeld, or KeyReleased event is fired and only the Controllers with the particular key(s) bound respond to the event and execute their associated Methods.
After that you changed X and Y coordinates o the Entity using specific component, you just redraw scene, and Entity will appear into the a new position. Where is actually the problem. ?
You have an Entity that is transformed in any possible way with (say) PositionComponent, RotationComponent, ScalComponent, TextureComponent and so on, but have simple Redraw() method which renders all Entites on the scene in visible frustrum within a current state of each one.
How about a tree of types focused on these high-level behaviors?: i.e. a Jump class would, given an object, know how to make it jump. Jump might be derived from Move if there is sufficient commonality, etc. More complex behaviors would then be composed of simpler behaviors heirarchically.

How to implement undo functionality?

In my application I want to provide the user with a small undo functionality. There aren't many actions than can be undone by the user. Particularly the actions are:
Add notes to an object
Color an object
Tag a objcet with a string
Now I thought about how to implement this. I first thought of a Action Class that is the abstract base class for the 3 different actions that can be taken by the user. Every time the user takes on of these actions, a new appropriate instance of a subclass of this abstract Action class is created and inserted into a list that contains all actions.
Whenever the user wants to undo something, the list is displayed to the user and he can choose which action he want to undo.
Now I was thinking what has to be stored in such an action object:
the state of the object before the action
the actual action that was taken (e.g. the string that was added to a object's notes)
I'm not sure if this is enough. I also thought about something like a chronological ordering, but this should be necessary since the list can be maintained chronologically correct.
Are there any other things I should consider?
Undo/redo is commonly implemented with the Command Pattern. The Action class can be used as the basis for this, but you need a 'do' action and an 'undo' action within each command. Here is an example of this in practice.
You should probably store the commands executed in a stack as it makes it much easier to implement and much easier for the user to follow.
You could do something simple like this:
Stack<Action> undoStack = new Stack<Action>();
void ChangeColor(Color color)
{
var original = this.Object.Color;
undoStack.Push(() => this.Object.Color = original);
this.Object.Color = color;
}
you should implement the Command Pattern for every action you want undo:
how to implement undo/redo operation without major changes in program
For Correct and proven implememtation for UNDO functionality is Command Pattern
Its hard to overlook this Simple-Undo-redo-library-for-Csharp-NET when adding Undo/Redo functionality to existing projects.

Categories