我正在使用 MVVM 模式并且有一个未完全更新的数据绑定列表框。
有一个模型视图包含绑定到列表的可观察机器集合:
<ListBox Name="MachinesList"
Height="300"
Width="290"
DataContext="{Binding Path=AllMachines}"
SelectionMode="Single"
ItemsSource="{Binding}" SelectionChanged="MachinesList_SelectionChanged"
HorizontalAlignment="Right"
>
集合 AllMachines 包含一个可观察的 MachineModelViews 集合,这些集合又绑定到一个 MachineView,该 MachineView 显示机器的名称和位置:
<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 的标签会更新,其他两个仍保留在列表框中。我已经确认该集合实际上正在正确更新和删除 MachineModelView,但是带有名称的标签和带有“位置:”的“标签标签”如何继续存在,直到重新启动应用程序:
前:
删除后:
应用重启后:
删除按钮调用一个命令,该命令从支持 AllMachines 属性的私有成员和存储库(最终通过实体框架插入数据库)中删除项目:
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 中只能有一个具有名称的项目(这由存储库中的添加逻辑和命令本身处理),因此删除“第一个”应该没问题。
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];
}