2

I want a button to show app settings window like this:

<Window.Resources>
    <local:SettingsWindow x:Key="SettingsWnd"/>
</Window.Resources>
<Window.DataContext>
    <local:MyViewModel/>
</Window.DataContext>
<Button Command="{Binding ShowSettingsCommand}"
    CommandParameter="{DynamicResource SettingsWnd}"/>

The ViewModel kinda thing:

class MyViewModel : BindableBase
{
    public MyViewModel()
    {
        ShowSettingsCommand = new DelegateCommand<Window>(
                w => w.ShowDialog());
    }

    public ICommand ShowSettingsCommand
    {
        get;
        private set;
    }
}

The problem is that it only works one time because you can't reopen previously closed windows. And apparently, the XAML above does not make new instances to open like that.

Is there a way to pass new window as CommandParameter every time the command is called?

Yegor
  • 2,514
  • 2
  • 19
  • 27
  • You are using a resource and closing it when you are done. You could reassign the resource after the `ShowDialog` call to a new resource. – Ron Beyer Aug 11 '15 at 19:48
  • I'm trying not to reference the settings window type in the code. "Reassigning the resource" would make me do that, wouldn't it? – Yegor Aug 11 '15 at 19:54
  • Yes, but `ShowDialog` calls the `Close` on the window, which basically destroys the resource you create in the XAML. You have to create a new one somewhere, either don't use a resource and do it completely in the command, or recreate the dialog for use next time after showing the dialog. – Ron Beyer Aug 11 '15 at 19:55

1 Answers1

2

Does this converter solve your problem?

class InstanceFactoryConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var type = value.GetType();

        return Activator.CreateInstance(type);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

...

<Window.Resources>
    <local:SettingsWindow x:Key="SettingsWnd"/>
    <local:InstanceFactoryConverter x:Key="InstanceFactoryConverter"/>
</Window.Resources>

...

<Button Command="{Binding ShowSettingsCommand}"
    CommandParameter="{Binding Source={StaticResource SettingsWnd}, Converter={StaticResource InstanceFactoryConverter}}"/>
Glen Thomas
  • 10,190
  • 5
  • 33
  • 65
  • Sorry, but that's not quite an answer to the question. I would like to avoid introducing dependencies in the code. Probably should've made myself clear about that. – Yegor Aug 12 '15 at 03:06
  • Yeah, that looks like my own approach with `CommandParameter="{x:Type local:SettingsWindow}"` and `(Activator.CreateInstance(w) as Window).ShowDialog()` in the `DelegateCommand`. If there's no alternative in a few days, I'll have to accept this solution. Thanks. – Yegor Aug 12 '15 at 08:20