I am very to Modern UI Programming and now i got stuck in a small C# WPF Application which is basically a learning project of MVVM design pattern.
I have a DataGrid and some Buttons to handle data operation (add, edit, delete).
What i want to achieve: the edit button should not be enable, when no row in grid is selected.
edit button:
<Button Width="126" Height="22" Content="Edit" Margin="5,5,5,5" Command="{Binding KontoEdit}" />
grid:
<DataGrid ItemsSource="{Binding Konten}" SelectedItem="{Binding SelectedKonto}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=KtoNr}" Header="Nr" IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Path=Name}" Header="Name" IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Path=KtoArt}" Header="Kontoart" IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Path=KtoKlasse}" Header="Kontenklasse" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
view model:
public class MainViewModel : INotifyPropertyChanged
{
KontenDB ctx = new KontenDB();
public MainViewModel()
{
FillKonten();
CanKontoEditExecute = true ;
KontoEdit = new RelayCommand(o => { DoKontoEdit(SelectedKonto); }, param => CanKontoEditExecute);
}
#region //Commands
public void DoKontoEdit(Konten k)
{
//Edit the Selected Item
}
private ICommand _kontoEdit;
public ICommand KontoEdit
{
get
{
return _kontoEdit;
}
set
{
_kontoEdit = value;
}
}
private bool _canKontoEditExecute;
public bool CanKontoEditExecute
{
get
{
return _canKontoEditExecute;
}
set
{
_canKontoEditExecute = value;
}
}
#endregion //Commands
private void FillKonten()
{
var q = (from k in ctx.Konten
select k).ToList();
Konten = new ObservableCollection<Konten>(q);
}
private ObservableCollection<Konten> _konten;
public ObservableCollection<Konten> Konten
{
get
{
return _konten;
}
set
{
_konten = value;
NotifyPropertyChanged();
}
}
private Konten _selectedKonto;
public Konten SelectedKonto
{
get
{
return _selectedKonto;
}
set
{
_selectedKonto = value;
NotifyPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
model is generated by EF6.
edit: RelayCommand class:
public class RelayCommand : ICommand
{
private Action<object> execute;
private Predicate<object> canExecute;
private event EventHandler CanExecuteChangedInternal;
public RelayCommand(Action<object> execute)
: this(execute, DefaultCanExecute)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
if (canExecute == null)
{
throw new ArgumentNullException("canExecute");
}
this.execute = execute;
this.canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
CanExecuteChangedInternal += value;
}
remove
{
CommandManager.RequerySuggested -= value;
CanExecuteChangedInternal -= value;
}
}
public bool CanExecute(object parameter)
{
return canExecute != null && canExecute(parameter);
}
public void Execute(object parameter)
{
execute(parameter);
}
public void OnCanExecuteChanged()
{
EventHandler handler = CanExecuteChangedInternal;
if (handler != null)
{
handler.Invoke(this, EventArgs.Empty);
}
}
public void Destroy()
{
canExecute = _ => false;
execute = _ => { return; };
}
private static bool DefaultCanExecute(object parameter)
{
return true;
}
}
So how can i achieve that when: no row in datagrid is selected or SelectedKonto is null the CanKontoEditExecute property changes to false?
Thanks a lot for your help!
Bring in following corrections
SelectedItem="{Binding SelectedKonto, Mode=TwoWay}"
KontoEdit = new RelayCommand(o => { DoKontoEdit(SelectedKonto); }, param => SelectedKonto != nulll);
private object _selectedItem;
public object SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
PropertyChanged(this,new PropertyChangedEventArgs("SelectedItem"));
}
}