列表框itemssource不会使用源更新

时间:2012-03-27 09:24:25

标签: wpf c#-4.0 binding mvvm listbox

我的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属性具有所需的值。

非常感谢任何帮助。

1 个答案:

答案 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对魔术字符串的依赖,但我还没有使用其中任何一种。