ObservableCollection不会在后面的代码中绑定到ListBox

时间:2012-01-27 21:43:42

标签: wpf binding collections listbox observable

我想将一个列表框绑定到后面的代码中的可观察集合。这就是我用于绑定的内容:

Binding binding = new Binding();
binding.Source = symTable;
substanceList.SetBinding(ListBox.ItemsSourceProperty, binding);

symTable继承自ObservableCollection,Count属性会适当更新,因此我知道我正在添加元素,但列表框却没有。我不知道要设置路径是什么,因为在XAML中它被绑定到整个列表。

注意:将单个项目添加到ListBox时会显示它们,因此它不是显示问题。我也尝试过:

this.Resources.Add("symTable", symTable);

在窗口构造函数中,然后是:

但它说无法解析资源。

我也尝试将其作为资源添加到XAML中,但它不再起作用: //在窗口的资源中。

<s:SymbolTable x:Key="symTable"/> 
...
<ListBox x:Name="substanceList" ItemsSource="{Binding Source={StaticResource symTable}}"/>

然后在代码背后:

symTable =(SymbolTable)this.FindResource(“symTable”);

有没有人知道在代码隐藏或XAML中执行此操作的任何其他方法,我认为ElementName是指代码背后定义的对象。

以下是symTable的类定义的一部分:

public class SymbolTable : ObservableCollection<Substance>
{
    Dictionary<string, Substance> symbolTable;
    ...
    public Substance Insert(Substance s)
    {

        if (!symbolTable.ContainsKey(s.Name))
        {
            symbolTable.Add(s.Name, s);
            Items.Add(s);
        }

        return symbolTable[s.Name];
    }

注意好吧所以我刚注意到最奇怪的事情,Items.Add没有引发INotifyChanged事件。我在我的Insert方法中使用了Items.Add,我猜测Items.Add没有引发一个INotifyChanged事件,所以ListBox没有得到更新,但是什么时候Add而不是Items.Add然后它工作了。你知道情况确实如此吗?

3 个答案:

答案 0 :(得分:1)

好的,按照您对问题的评论,这里是如何在XAML中将SymbolTable声明为资源以及如何将ListBox绑定到它。请注意XAML名称空间声明“local”,它引用本地名称空间/程序集,在我的测试项目中名为ListBindingTest

<Window x:Class="ListBindingTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:ListBindingTest"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:SymbolTable x:Key="symTable"/>
    </Window.Resources>
    <Grid>
        <ListBox ItemsSource="{Binding Source={StaticResource symTable}}"/>
    </Grid>
</Window>

您可以在窗口类中的代码中访问SymbolTable资源,如下所示:

SymbolTable st = (SymbolTable)Resources["symTable"];
st.Add(new Substance());

答案 1 :(得分:0)

DisplayMemberPath需要是symTable的公共属性。

答案 2 :(得分:0)

您可以随时直接在列表框中设置ItemSource。

substanceList.ItemsSource = symTable;