reggaeguitar
reggaeguitar

Reputation: 1804

Pass Parameter to Generic Method at Runtime

I'm trying to refactor the following code into a single method

if (message.Type == WindowType.DataSourcePickerTest)
{
    var vm = SimpleIoc.Default.GetInstance<DataSourcePickerViewModel>();
    var win = new PickerWindowTest { DataContext = vm };
    var result = win.ShowDialog() ?? false;
    if (result)
        Messenger.Default.Send(vm);
}
else if (message.Type == WindowType.BaselineSave)
{
    var vm = SimpleIoc.Default.GetInstance<BaselineSaveAsViewModel>();
    var win = new BaselineSaveAs { DataContext = vm };
    var result = win.ShowDialog() ?? false;
    if (result)
        Messenger.Default.Send(vm);
}

The only difference between the two branches is the type of the ViewModel and Window (vm and win). So far I have

private void LaunchWindow(Type viewModelType, Type windowType)
{
    var vm = SimpleIoc.Default.GetInstance<viewModelType>();
}

but I'm getting a compilation error 'The type or namespace name 'viewModelType' could not be found'. Is there a way to refactor this if statement without resorting to reflection? Thanks in advance

Upvotes: 1

Views: 71

Answers (1)

D Stanley
D Stanley

Reputation: 152626

You could factor out the inner part and call it generically, but it requires that the window class inherit from some base type that have a DataContext property (you might also need restrictions on T depending on the type of the DataContext property):

if (message.Type == WindowType.DataSourcePickerTest)
{
    SubMethod<DataSourcePickerViewModel, PickerWindowTest>();
}
else if (message.Type == WindowType.BaselineSave)
{
    SubMethod<BaselineSaveAsViewModel, BaselineSaveAs>();
}

public void SubMethod<T, U>() where U : Window, new()
{
    var vm = SimpleIoc.Default.GetInstance<T>();
    var win = new U { DataContext = vm };
    var result = win.ShowDialog() ?? false;
    if (result)
        Messenger.Default.Send(vm);
}

Upvotes: 3

Related Questions