我的XAML中有两个列表框,它们都是多选的。我已使用Samuel Jack's solution同步列表框的selectedItems。
<ListBox x:Name="lbOrg" HorizontalAlignment="Left" Grid.Column="1" Grid.Row="0"
Margin="15,3,5,3" Width="200" Height="120" ItemsSource="{Binding AvailableOrg}"
LSync:MultiSelectorBehaviours.SynchronizedSelectedItems="{Binding SelectedOrg}"
SelectionMode="Extended" DisplayMemberPath="OrgShortName"/>
<ListBox x:Name="lbSite" HorizontalAlignment="Left" Grid.Column="3" Grid.Row="0"
Margin="15,3,5,3" Width="200" Height="120" ItemsSource="{Binding AvailableSites}"
LSync:MultiSelectorBehaviours.SynchronizedSelectedItems="{Binding SelectedSites}"
SelectionMode="Extended" DisplayMemberPath="SiteShortName"/>
lbSite 需要根据 lbOrg 中选择的值进行填充。因此,为了让ViewModel了解为 lbOrg 更改的选择,我正在处理 lbOrg 的Selected Items列表的选择更改事件并调用填充方法 lbSite 的值。
public void Load()
{
_selectedOrg = new ObservableCollection<object>();
_selectedSites = new ObservableCollection<object>();
_selectedOrg.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(_selectedOrg_CollectionChanged);
}
private void _selectedOrg_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (AvailableSites != null)
AvailableSites.Clear();
if(SelectedOrg != null && SelectedOrg.Count > 0)
{
foreach (object org in SelectedOrg)
{
if (AvailableSites == null || AvailableSites.Count == 0)
AvailableSites = WebClient.getSitesForOrg(((OrganizationModel)org).OrgId);
else
{
ObservableCollection<object> tempSiteList = WebClient.getSitesForOrg(((OrganizationModel)org).OrgId);
foreach (object site in tempSiteList)
{
AvailableSites.Add(site);
}
}
}
}
}
我已将属性定义为:
public ObservableCollection<object> SelectedOrg
{
get
{
return _selectedOrg;
}
set
{
_selectedOrg = value;
OnPropertyChanged("SelectedOrg");
}
}
public ObservableCollection<object> AvailableSites
{
get
{
return _availableSites;
}
set
{
_availableSites = value;
OnPropertyChanged("AvailableSite");
}
}
我的ViewModelBase实现了INotifyPropertyChanged。此外,属性被定义为ObservableCollection,其中对象是从两个属性中的单独自定义类转换而来的。
我想这本来应该很容易,但是由于一些奇怪的原因,列表框没有得到关于属性变化的通知,因此没有对源的更改反映在视图上。我已经使用后面代码中的lbOrg的Selection更改事件绑定了一个eventHandler,以检查lbSite的Itemssource是否得到更新,但是尽管AvailableSites属性具有所需的值。
非常感谢任何帮助。
答案 0 :(得分:2)
你错过了一个“s”。 :)
OnPropertyChanged("AvailableSite");
应该是
OnPropertyChanged("AvailableSites");
我的ViewModelBase中有一些代码在调试模式下检查字符串,它对于捕获这些错误非常有帮助:
[Conditional("DEBUG")]
private void CheckPropertyNameIsValid(string propertyName)
{
// INotifyPropertyChanged notifies via strings, so use
// this helper to check that the string is accurate in debug builds.
if (TypeDescriptor.GetProperties(this)[propertyName] == null)
throw new Exception("Invalid property name: " + propertyName);
}
还有各种优雅的解决方案可以完全消除INotifyPropertyChanged
对魔术字符串的依赖,但我还没有使用其中任何一种。