2

I have a function that is designed to create an instance of a window and return me a RelayCommand (basically, it's just an MVVMLite helper method:

public static RelayCommand NavigateTo(Type navigateTo)
{
    var relayCmd = new RelayCommand (() => Navigate(navigateTo));
    return relayCmd;
}

private static void Navigate(Type navigateTo)
{
    var newWin = Activator.CreateInstance(navigateTo);
    ((Window)newWin).Show();
}

I then call this in a separate class like this:

this.MyCommand = Navigation.NavigateTo(View.MyView);

MyView is a valid Window, however, I get the following compile error:

The best overloaded method match for 'MyProject.Navigation.NavigateTo(System.Type)' has some invalid arguments

I can make it work, by doing this:

this.MyCommand = Navigation.NavigateTo(typeof(View.MyView));

My question is: why? I'm passing a type and expecting a type. Also, is there a way that I can get my NavigateTo function to simply accept the class name of the Window?

Paul Michaels
  • 16,185
  • 43
  • 146
  • 269

3 Answers3

1

I'm passing a type and expecting a type.

You try to pass a type, but you cannot do this in .Net. You can only pass System.Type objects. You can get a System.Type object from class, by writing typeof(MyClass). You can get a System.Type object from object, by writing obj.GetType().

You need to understand the difference between class / type and object / instance.

Ark-kun
  • 6,358
  • 2
  • 34
  • 70
1

It turns out that what I wanted was to use generics, which allows me to pass the class type and deal with it in the function:

    public static RelayCommand NavigateTo<T>()
    {
        Type dest = typeof(T);
        var relayCmd = new RelayCommand(() => Navigate(dest));
        return relayCmd;
    }

    private static void Navigate<T>()
    {
        object dest = Activator.CreateInstance<T>();            
        ((Window)dest).Show();            
    }

And call like this:

this.MyCommand = Navigation.NavigateTo<MyView>();
Paul Michaels
  • 16,185
  • 43
  • 146
  • 269
  • Fun thing is that I've just recently answered with a similar statically-typed navigation for Windows Phone: http://stackoverflow.com/questions/20004086/is-there-a-typesafe-way-of-navigating-between-screens-in-windows-phone/20063659#20063659 – Ark-kun Dec 04 '13 at 01:33
0

You need to be using typeof to pass the type otherwise you are passing a class. The typeof grabs the System.Type which is what you are expecting, otherwise it is looking for a definition in that class. You could also use .GetType().

Recursor
  • 542
  • 5
  • 18
  • How can I pass `View.MyView` without using `typeof()` or `.GetType()`? – Paul Michaels Nov 25 '13 at 16:49
  • I honestly don't think you can. http://msdn.microsoft.com/en-us/library/vstudio/58918ffs.aspx. You are asking for a System.Type. If you try to just pass in View.MyView you are passing in a 'type' but you are passing in a System.Type. – Recursor Nov 25 '13 at 17:11