I am trying to get used to MVVM and WPF for a month. I am trying to do some basic stuff, but I am constantly running into problems. I feel like I solved most of them by searching online. But now there comes the problem with Commands.
Q: I saw that they are using RelayCommand, DelegateCommand or SimpleCommand. Like this:
public ICommand DeleteCommand => new SimpleCommand(DeleteProject);
Even though I create everything like they did, I am still having the part => new SimpleCommand(DeleteProject);
redly underlined.
So far I am working around it by creating command class for every command, but that does not feel like the right way to go.
- Q: I will also post whole project and I would like to know if I am doing anything wrong or what should I improve.
xaml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="380" Width="250">
<StackPanel DataContext="{Binding Source={StaticResource gallery}}" Margin="10">
<ListView DataContext="{Binding Source={StaticResource viewModel}}"
SelectedItem="{Binding SelectedGallery}"
ItemsSource="{Binding GalleryList}"
Height="150">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="100" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Header="Path" Width="100" DisplayMemberBinding="{Binding Path}"/>
</GridView>
</ListView.View>
</ListView>
<TextBlock Text="Name" Margin="0, 10, 0, 5"/>
<TextBox Text="{Binding Name}" />
<TextBlock Text="Path" Margin="0, 10, 0, 5" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<TextBox Text="{Binding Path}" Grid.Column="0"/>
<Button Command="{Binding Path=ShowFolderClick, Source={StaticResource viewModel}}"
CommandParameter="{Binding}"
Content="..." Grid.Column="1" Margin="10, 0, 0, 0"/>
</Grid>
<Grid Margin="0, 10, 0, 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Command="{Binding Path=AddClick, Source={StaticResource viewModel}}"
CommandParameter="{Binding}" Content="Add" Grid.Column="0" Margin="15,0,0,0" />
<Button Command="{Binding Path=DeleteClick, Source={StaticResource viewModel}}"
Content="Delete" Grid.Column="2" Margin="0,0,15,0" />
</Grid>
</StackPanel>
Model:
class Gallery : INotifyPropertyChanged
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
OnPropertyChanged("Name");
}
}
private string _path;
public string Path
{
get
{
return _path;
}
set
{
_path = value;
OnPropertyChanged("Path");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(params string[] propertyNames)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
foreach (string propertyName in propertyNames) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
handler(this, new PropertyChangedEventArgs("HasError"));
}
}
}
ModelView:
class GalleryViewModel : INotifyPropertyChanged
{
public GalleryViewModel()
{
GalleryList = new ObservableCollection<Gallery>();
this.ShowFolderClick = new ShowFolderDialog(this);
this.AddClick = new AddGalleryCommand(this);
this.DeleteClick = new DeleteGalleryCommand(this);
}
private ObservableCollection<Gallery> _galleryList;
public ObservableCollection<Gallery> GalleryList
{
get { return _galleryList; }
set {
_galleryList = value;
OnPropertyChanged("GalleryList");
}
}
private Gallery _selectedGallery;
public Gallery SelectedGallery
{
get { return _selectedGallery; }
set {
_selectedGallery = value;
OnPropertyChanged("SelectedGallery");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(params string[] propertyNames)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
foreach (string propertyName in propertyNames) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
handler(this, new PropertyChangedEventArgs("HasError"));
}
}
public AddGalleryCommand AddClick { get; set; }
public void AddGalleryClick(Gallery gallery)
{
Gallery g = new Gallery();
g.Name = gallery.Name;
g.Path = gallery.Path;
GalleryList.Add(g);
}
public DeleteGalleryCommand DeleteClick { get; set; }
public void DeleteGalleryClick()
{
if (SelectedGallery != null)
{
GalleryList.Remove(SelectedGallery);
}
}
public ShowFolderDialog ShowFolderClick { get; set; }
public void ShowFolderDialogClick(Gallery gallery)
{
System.Windows.Forms.FolderBrowserDialog browser = new System.Windows.Forms.FolderBrowserDialog();
string tempPath = "";
if (browser.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
tempPath = browser.SelectedPath; // prints path
}
gallery.Path = tempPath;
}
}
Commands:
class AddGalleryCommand : ICommand
{
public GalleryViewModel _viewModel { get; set; }
public AddGalleryCommand(GalleryViewModel ViewModel)
{
this._viewModel = ViewModel;
}
public bool CanExecute(object parameter)
{
/*if (parameter == null)
return false;*/
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
this._viewModel.AddGalleryClick(parameter as Gallery);
}
}
class DeleteGalleryCommand : ICommand
{
public GalleryViewModel _viewModel { get; set; }
public DeleteGalleryCommand(GalleryViewModel ViewModel)
{
this._viewModel = ViewModel;
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
this._viewModel.DeleteGalleryClick();
}
}
class ShowFolderDialog : ICommand
{
public GalleryViewModel _viewModel { get; set; }
public ShowFolderDialog(GalleryViewModel ViewModel)
{
this._viewModel = ViewModel;
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
this._viewModel.ShowFolderDialogClick(parameter as Gallery);
}
}
Thanks for your time reading so far, I will appreciate every advice I will get.