MVVM パターンを使用しており、完全に更新されていないデータバインド リストボックスがあります。
リストにバインドされているマシンの監視可能なコレクションを含むモデル ビューがあります。
<ListBox Name="MachinesList"
Height="300"
Width="290"
DataContext="{Binding Path=AllMachines}"
SelectionMode="Single"
ItemsSource="{Binding}" SelectionChanged="MachinesList_SelectionChanged"
HorizontalAlignment="Right"
>
コレクション AllMachines には、マシンの名前と場所を示す MachineView にバインドされている MachineModelViews の監視可能なコレクションが含まれています。
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Label Name="NameLabel" Content="{Binding Path=Name}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Width="50" />
<Label Content="Location:" Width="120"
HorizontalAlignment="Right"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Target="{Binding ElementName=locationLabel}"
/>
<Label Content="{Binding Path=Location.Name}" Name="locationLabel" HorizontalContentAlignment="Center" Width="60"/>
</StackPanel>
問題:
コレクションに値が追加されると、問題なく更新されます。ただし、マシンが削除されると、Location.Name にバインドされたラベルのみが更新され、他の 2 つはリストボックスに残ります。コレクションが実際に MachineModelView を正しく更新および削除していることを確認しましたが、アプリケーションが再起動されるまで、その名前のラベルと「場所:」の「ラベル ラベル」がどのように存在し続けるかを確認しました。
前:
削除後:
アプリの再起動後:
削除ボタンは、AllMachines プロパティをサポートするプライベート メンバーとリポジトリ (最終的には Entity Framework を介してデータベースにプラグインする) からアイテムを削除するコマンドを呼び出します。
RelayCommand _deleteCommand;
public ICommand DeleteCommand
{
get
{
if (_deleteCommand == null)
{
_deleteCommand = new RelayCommand(
param => this.Delete(),
null
);
}
return _deleteCommand;
}
}
void Delete()
{
if (_selectedMachine != null && _machineRepository.GetMachines().
Where(i => i.Name == _selectedMachine.Name).Count() > 0)
{
_machineRepository.RemoveMachine(_machineRepository.GetMachines().
Where(i => i.Name == _selectedMachine.Name).First());
_allMachines.Remove(_selectedMachine);
}
}
注: AllMachines には名前を持つアイテムが 1 つしか存在できないため (これは、リポジトリとコマンド自体の追加ロジックによって処理されます)、「最初の」アイテムを削除しても問題ありません。
AllMachines プロパティ:
public ObservableCollection<MachineViewModel> AllMachines
{
get
{
if(_allMachines == null)
{
List<MachineViewModel> all = (from mach in _machineRepository.GetMachines()
select new MachineViewModel(mach, _machineRepository)).ToList();
_allMachines = new ObservableCollection<MachineViewModel>(all);
}
return _allMachines;
}
private set
{
_allMachines = value;
}
}
選択変更イベント ハンドラー:
private void MachinesList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0 && e.AddedItems[0] is MachineViewModel)
((MachinesViewModel)this.DataContext).SelectedMachine = (MachineViewModel)e.AddedItems[0];
}