I am brand new to basically all of this and am trying to learn C# in the context of MVVM. This will be a simple CRUD program and right now I am stuck on the deletion of a ComboBox
's SelectedItem
from the corresponding collection.
Relevant ViewModel code:
public class AlbumViewModel
{
private ObservableCollection<AlbumModel> albums;
public AlbumViewModel()
{
this.albums = new ObservableCollection<AlbumModel>();
LoadAlbums();
}
public ObservableCollection<AlbumModel> Albums
{
get { return this.albums; }
}
public void LoadAlbums()
{
albums.Add(new AlbumModel("No Love/Deep Web", "Death Grips"));
albums.Add(new AlbumModel("In Defense of the Genre", "Say Anything"));
albums.Add(new AlbumModel("Picaresque", "The Decemberists"));
albums.Add(new AlbumModel("In Evening Air", "Future Islands"));
albums.Add(new AlbumModel("You're Gonna Miss It All", "Modern Baseball"));
}
#region RelayCommand
private RelayCommand _deleteCommand;
public ICommand DeleteCommand
{
get
{
if (_deleteCommand == null)
{
_deleteCommand = new RelayCommand(param => DeleteItem());
}
return _deleteCommand;
}
}
#endregion
#region DeleteItem()
private AlbumModel SelectedItem { get; set; }
private void DeleteItem()
{
if (SelectedItem != null)
{
this.albums.Remove(SelectedItem);
this.SelectedItem = null;
}
}
#endregion
}
Relevant Model code:
public class AlbumModel : INotifyPropertyChanged
{
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
// AlbumModel members, properties, constructor
}
#region RelayCommand
public class RelayCommand : ICommand
{
// fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
// ctors
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
// ICommand members
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested += value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
Relevant XAML:
<Window x:Class="AlbumsCRUD2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:AlbumsCRUD2.ViewModels"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:AlbumViewModel />
</Window.DataContext>
<Window.Resources>
<local:AlbumViewModel x:Key="albums" />
</Window.Resources>
<Grid>
<GroupBox Grid.Row="1" Grid.Column="1" HorizontalContentAlignment="Center" Header="View Existing">
<StackPanel>
<Label Content="Album" />
<ComboBox Name="albumComboBox"
ItemsSource="{Binding Path=Albums}"
DisplayMemberPath="AlbumName"
SelectedItem="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Label Content="Artist" />
<TextBox Text="{Binding ElementName=albumComboBox, Path=SelectedItem.ArtistName}"
IsEnabled="False" />
<Button Name="deleteBtn" Width="100" Margin="30"
Command="{Binding DeleteItem}"
Content="Delete" />
</StackPanel>
</GroupBox>
</Grid>
</Window>
And, of course, the errors in Output:
System.Windows.Data Error: 40 : BindingExpression path error: 'SelectedItem' property not found on 'object' ''AlbumViewModel' (HashCode=12507741)'. BindingExpression:Path=SelectedItem; DataItem='AlbumViewModel' (HashCode=12507741); target element is 'ComboBox' (Name='albumComboBox'); target property is 'SelectedItem' (type 'Object')
System.Windows.Data Error: 40 : BindingExpression path error: 'DeleteItem' property not found on 'object' ''AlbumViewModel' (HashCode=12507741)'. BindingExpression:Path=DeleteItem; DataItem='AlbumViewModel' (HashCode=12507741); target element is 'Button' (Name='deleteBtn'); target property is 'Command' (type 'ICommand')
I suspect it's an error with my data bindings, but I'm having a hard time deciphering the meaning of the errors. I would appreciate any perspective on what is going wrong!
答案 0 :(得分:2)
SelectedItem
should be public. Bindings need this.DeleteItem
), not the command (DeleteCommand
).