You should have one View Model per View; not per item in your view (in this case, buttons). An easy way to do what you are describing would be to use the CommmandParameter
property to pass in your exe names:
<Button Content="Launch IE" Command="{Binding LaunchAppCommand}" CommandParameter="IExplorer.exe"/>
<Button Content="Launch Notepad" Command="{Binding LaunchAppCommand}" CommandParameter="notepad.exe"/>
<Button Content="Launch Chrome" Command="{Binding LaunchAppCommand}" CommandParameter="chrome.exe"/>
With your command:
public ICommand LaunchAppComand {get; private set;}
...
public MyViewModel()
{
LaunchAppCommand = new DelegateCommand(LaunchApp);
}
...
private void LaunchApp(object parameter)
{
string processName = (string)parameter;
Process launchProc = new Process();
launchProc.StartInfo.FileName = processName;
launchProc.Start();
}
To avoid hard coding all your buttons you could use an ItemsControl
, which does set an individual data context for each template it creates. To do so, you need a collection of data classes, and a slightly different way to get to your command:
//ProcessShortcut.cs
public class ProcessShortcut
{
public string DisplayName {get; set;}
public string ProcessName {get; set;}
}
//MyViewModel.cs, include the previous code
//INotifyPropertyChanged left out for brevity
public IEnumerable<ProcessShortcut> Shortcuts {get; set;}
public MyViewModel()
{
Shortcuts = new List<ProcessShortcut>()
{
new ProcessShortcut(){DisplayName = "IE", ProcessName="IExplorer.exe"},
new ProcessShortcut(){DisplayName = "Notepad", ProcessName="notepad.exe"},
new ProcessShortcut(){DisplayName = "Chrome", ProcessName="chrome.exe"},
};
}
//MyView.xaml
<Window x:Name="Root">
...
<ItemsControl ItemsSource="{Binding Shortcuts}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding DisplayName, StringFormat='{}Start {0}'}"
Command="{Binding ElementName=Root, Path=DataContext.LaunchAppCommand}"
CommandParameter="{Binding ProcessName}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
...
</Window>
Because an ItemsControl
sets the DataContext
inside the template to the bound item you need an ElementName
binding to get to the command, and don't need to qualify access to members of ProcessShortcut
. In the long run, this is the approach you usually want to take when you have repetitious controls like this.