2016-07-11 7 views
0

私はこれを基本的にすべて取り入れており、MVVMのコンテキストでC#を学ぼうとしています。これはシンプルなCRUDプログラムで、今は対応するコレクションからComboBoxSelectedItemを削除することに固執しています。ComboBox SelectedItemをコレクションから削除する

関連のViewModelコード:

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 


} 

関連するモデルコード:

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); 
    } 

関連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> 

そして、もちろん、出力中のエラー:

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') 

データバインディングでエラーが発生していると思われますが、エラーの意味を解読するのは苦労しています。私は何がうまくいかないかについてのあらゆる視点に感謝します!

+0

重複したVMインスタンスとは何ですか、リソースの1つはDataContextですか? –

答えて

2
  1. SelectedItemは公開する必要があります。バインディングにはこれが必要です。
  2. コマンド(DeleteCommand)ではなく、メソッド(DeleteItem)にバインドしようとしました。
+0

ありがとうございました!彼らはこのような単純なもののように見えるので、見落とすのは恥ずかしいですが、私が言ったように、私はこのコンセプト全体にまったく新しいものであり、それを学ぶことはプロセスです。以前のコメントの「ビューファースト」の意味を詳しく解説できますか?そして重複したVM?それは本当に助けになるだろう。 – korina

+1

VMインスタンスが 'Window.DataContext'と' Window.Resources'の両方にあります。 'DataContext'には1つしかなければなりません。あるいは、後で' DataContext'でリソースにリファレンスとリファレンスを作成して参照してください。ビューファーストとは、ビューの中にビューモデルを作成したように(2回)作成するということです。私が見ているように、WPFはすべての場合に適切に対処する用意があるという悪いアプローチです。代わりに、ビュー・モデル・ファーストがあります。詳細については、googleまたはstack-overflowを検索してください。 –

+0

@korina:http://stackoverflow.com/questions/3763072/what-are-the-pros-and-cons-of-view-first-vs-viewmodel-first-in-the-mvvm-pattern –

関連する問題