Command Parameter with RelayCommand - wpf

I'm using a version of the common RelayCommand class and trying to pass a command parameter but not having success. I get the following error:
Error 29 Method 'Private Sub KeyPadPressExecute(param As Object)' does not have a signature compatible with delegate 'Delegate Sub Action()'.
I've looked at the many examples of using parameters with commands, but I can't make sense out of them. I don't understand where I'm supposed to get the parameter from that will be passed on to KeyPadPressExecute().
Here's the relevant code:
Private Sub KeyPadPressExecute(param As Object)
Debug.Print(param.ToString)
End Sub
Private Function CanKeyPadPressExecute() As Boolean
Return True
End Function
Public ReadOnly Property KeyPadPress() As ICommand
Get 'Error occurs on next line
Return New RelayCommand(AddressOf KeyPadPressExecute, AddressOf CanKeyPadPressExecute)
End Get
End Property
What my XAML looks like:
<Button Command="{Binding KeyPadPress}" CommandParameter="1" Width="84"></Button>
I'm using VS 2012 and targeting .NET 4.5.
Note: My original post said I was using MicroMVVM. Closer inspect of the project indicates that the assembly named MicroMVVM is not related to the MicroMVVM framework hosted at codeplex. This project was started by someone else, thus the confusion.

From a RelayCommand implementation seen at GitHub, one can tell that the class effectively hides and swallows the command parameter. Perhaps you should try to use the generic version of the class instead: RelayCommand(Of T). The run-time exception is pretty clear: there's a mismatch between the MicroMVVM class's constructor, taking only a blunt Sub Action() delegate; and your command's execute handler, taking an object argument.
NB: Please forgive my bad VB, it's not my mother tongue.
Update: I see that MicroMVVM is hosted at CodePlex, but there's no RelayCommand class in there (apparently replaced by the smarter DelegateCommand class). The link to the probably unrelated project at GitHub still serves its purpose as an example and source of information. Comments are welcome.

Related

Why use Func<> in controller constructor parameters in MVVM applications

I'm seeing, more and more code like the code below in an MVVM application (WPF and Prism). Controllers have the following code fragments:
public class DispenseOptionController : IDispenseOptionController
{
protected readonly Func<IPharmacyCdmServiceSimpleClient> CdmClient;
protected readonly Func<IPatientServiceSimpleClient> PatientClient;
public DispenseOptionController(Func<IPharmacyCdmServiceSimpleClient> cdmClient, Func<IPatientServiceSimpleClient> patientClient)
{
CdmClient = cdmClient;
PatientClient = patientClient;
}...
I'm trying to understand the role that Func<> plays here. It seems that this delegate is used as parameters to the constructor. Can someone explain to me why anyone would use Func<> in this particular case? And can Func<> be replaced with anything else?
A Func<> is nothing but the Encapsulation of a method that one or more parameter and returns a value of the type specified by the TResult parameter.
You could see some use cases here

Loading dependencies in Unity Container in WinForms application

This is how the solution partially looks like.
Since I am using the Onion Architecture in a Winforms environment, hence I have the UI, Infrastructure and Core layers. All the layers are loosely coupled using Dependency Injection. What I want to achieve is that whenever a form from e.g. Accounts Forms (Class Library) is loaded, all the dependencies for that should be loaded in the UnityContainer i.e. types registered. These dependencies are interfaces and implementations present in Core and Infrastructure projects.
My confusion is that where should I write the code to register dependencies? What would be the Composition Root for this application? Please note that forms from e.g. Accounts Forms, HR Forms, etc are all loaded using reflection in the Main Windows application which references only the Base Forms Project.
After Eben Roux's suggestions
Here is how I am executing the wireup code when the assembly is loaded:
Dim assemb As System.Reflection.Assembly
...
...
If assemb IsNot Nothing Then
Dim type As Type = GetType(IDependencyWiring)
Dim modules As List(Of Type) = assemb.GetTypes().Where(Function(p) type.IsAssignableFrom(p) AndAlso p.IsClass).ToList()
For Each [module] As Type In modules
Dim argTypes As Type() = New Type() {}
Dim cInfo As ConstructorInfo = [module].GetConstructor(argTypes)
Dim dependencyWiringModule As IDependencyWiring = DirectCast(cInfo.Invoke(Nothing), IDependencyWiring)
dependencyWiringModule.WireUp()
Next
End If
Here's is the Module having the WireUp method:
Public Class AccountModule : Implements IDependencyWiring
Private Shared Container As IUnityContainer
Public Sub New()
Container = New UnityContainer()
End Sub
Public Sub WireUp() Implements IDependencyWiring.WireUp
Container.RegisterType(Of IInterface1, Class1)()
Container.RegisterType(Of IInterface2, Class2)()
Container.RegisterType(Of IInterface3, Class3)()
Container.RegisterType(Of IInterface4, Class4)()
End Sub
Public Shared Function Resolve(typeToResolve As Type) As Object
Return Container.Resolve(typeToResolve.GetType())()
End Function
End Class
So my questions now are:
Is it the right approach to store the Container as Shared and use it to resolve dependencies via Resolve method?
There is a problem in the way I am encapsulating the Resolve behavior of the Container. What would be the right syntax for that? I don't want to reference Unity on each of the form to be able to call the Resolve method, so I am encapsulating that i my own Resolve method. In this way I could easily replace the AccountModule with another one if I want to change the IOC Container without having the change the container references everywhere.
With this type of plug-in architecture you effectively end up with more than one composition root (of sorts). There will in all probability be some dependencies only your plug-in knows about and can wire up.
So part of your architecture should be the loading of the plug-ins. This probably happens somewhere in the main application in the wire-up bit (composition root) which would then give each plug-in the opportunity to perform its wiring.
Since not all plug-ins may need wiring one could make that explicit by using a seperate interface:
public interface IDependencyWiring
{
public void WireUp(IDependencyContainer container); // <-- changed to conform to update
}
And then in the main composition root:
foreach (var plugin in plugins)
{
var wiring = plugin as IDependencyWiring;
if (wiring != null)
{
wiring.WireUp(myContainer);
}
}
I hope that makes sense.
Update:
Firstly I would use a safe cast. TryCast in the VB.NET world. You could use dependency iversion to get rid of Unity from the actual plug-ins by using your own interface. Something like so:
public interface IDependencyContainer
{
void Register(Type type);
void Register<T>();
void Resolve(Type type);
void Resolve<T>();
}
Well, you would add what you need. Then pass in the reference to the container in the wire-up as I did up top public void WireUp(IContainer container);.
The Resolve behahiour is somewhat problematic in that you seem to be headed in a Service Locator direction. Try to get as much of the resolving done by the container by using constructor (or other) injection. Of course this works fine for Singleton components. For the Transient ones I'd rather use a Singleton factory that receives an instance of the IDependencyContainer (so that will also be registered), and it does the resolving (creation, really) for you.

How to use parameterless constructor with ninject di and winforms

I'm working on a WinForm application using ninject for dependency injection. My first problem was that the form being instantiated had a parameter (for DI). I added a parameterless constructor thinking this would help. The problem now is that the code inside the constructor with the parameter gets skipped. Here what it looks like:
On my main form:
private void mnuSettings_Click(object sender, System.EventArgs e)
{
frmSettings objForm = new frmSettings();
objForm.Owner=this;
objForm.Show();
}
In the frmSettings form:
private readonly IApplicationPropertiesInterface _applicationProperties;
public frmSettings()
{
InitializeComponent();
}
public frmSettings(IApplicationPropertiesInterface applicationProperties) : this()
{
_applicationProperties = applicationProperties;
}
When I call _applicationProperties.GetExtractFileSaveLocationDirectory() it blows up because the code to set _applicationProperties was never called.
Im wondering if I have structured this incorrectly, and what the best way to achieve this is. My goal is to call the parameterless constructor, but also set _applicationProperties.
Any assistance would be most grateful.
I'm guessing you might be expecting that having Ninject in the building will mena that new will work differently to normal. It doesn't - you need to be doing a kernel.Resolve<Something> for the DI to kick in. Note that most of these pitfalls are covered in detail on the wiki
Can you edit your answer to include details of what you're doing outside of this form please?
In the meantime, here are some previous questions that overlap significantly:-
What is the best practice for WinForms dialogs with ninject?
How to use Ninject in a Windows Forms application?

Accessing the UI thread to change dependancy properties in WPF

I'm trying to update a dependancy property in VB.Net 4.0 inside of an Async callback. I feel like I am doing this correctly but I'm still getting the "The calling thread cannot access this object because a different thread owns it." error. Does someone see a better way of using delegates in VB.Net 4.0?
Private WithEvents myObj as CallingObject
Private Delegate Sub MyErrorDel(ByVal strError as string)
Public Property ErrorMessage As String
Get
Return CStr(GetValue(ErrorMessageProperty))
End Get
Set(ByVal value As String)
SetValue(ErrorMessageProperty, value)
End Set
End Property
Private Sub MySub()
myObj.CallFuncAsync()
End Sub
Private Sub DisplayError(ByVal strError as String)
'Set Dependancy Property value Bound to UI Textbox
ErrorMessage = strError
End Sub
Private Sub myObj_CallFuncCompleted(Byval sender as Object, ByVal e as CallFuncEventArgs)
'Call delegate and pass in error string as argument
Dim delError as MyErrorDel
delError = New MyErrorDel(AddressOf DisplayError)
delError("An error occured")
Me.Dispatcher.Invoke(delError, System.Windows.Threading.DispatcherPriority.Normal, Nothing)
End Sub
Whenever ErrorMessage gets set inside of DisplayError an exception gets thrown, even though I am using the dispatcher to call DisplayError.
If anyone see any issues with the way I am trying to access Dependancy Properties from a async callback I would really appreciate the feedback.
Thanks for the help!
Oh and I'm pretty new at blogging about code issues. Any suggestions about how to better formulate this question would be welcome as well.
The problem might be that at the call to Me... you are already accessing an object owned by another thread, try to store a reference to the dispatcher beforehand or possibly use Application.Current.Dispatcher.
Since you didn't indicate the offending line, I suspect the problem here is that you're invokng your delegate in the line delError("An error occured") rather than waiting until you get to the dispatcher. Consider changing your CallFuncCompeted implementation to
Me.Dispatcher.Invoke(AddressOf DisplayError, "An error occureed")

VB.NET: WPF Single Instance

Has anyone using VB.NET 2010 been able to create a single instance application?
I've followed the MSDN sample but it does not have an Application.xaml file.
Converting any C# samples to VB doesn't work as I cannot override the Main sub in Application.xaml (C# calls it App.xaml).
You can try using a Mutex. In the projects properties, disable the application framework and set Sub Main as the startup object. Then add a Module to your project:
Imports System.Threading
Module EntryPoint
Sub Main()
Dim noPreviousInstance As Boolean
Using m As New Mutex(True, "Some Unique Identifier String", noPreviousInstance)
If Not noPreviousInstance Then
MessageBox.Show("Application is already started!")
Else
Dim mainWindow As New MainWindow()
Dim app As New Application()
app.Run(mainWindow)
End If
End Using
End Sub
End Module
With this method, you will have to take care of your app's shutdown by calling the Shutdown method of the application.
Here's a few possible solutions. I'd look through the whole thread here before deciding on one. Make sure you backup your code before trying any of these, so if one doesn't work, you can try another.
http://social.msdn.microsoft.com/forums/en-US/wpf/thread/6c15b837-9149-4b07-8a25-3266949621a7/

Resources