数据绑定 - 从数据库重新加载后更新数据时,列表框不会更新

时间:2013-11-06 06:25:35

标签: c# wpf xaml data-binding mvvm

我有一个列表框,其中包含从数据库填充的项目。现在我想在每次调用Add函数时用新的字符串值更新列表框。

我是用两种方式做到的。

  • 我将新值添加到数据库并更新了列表框绑定到的ViewModel类。这很好用。 (参见下面的AddNewNameFirstWay方法)

  • 我将新值添加到数据库,从数据库重新加载值并更新ViewModel。但这不起作用。 (参见下面的AddNewNameSecondWay方法)

这是我的ViewModel代码

public class ViewModel 
{
    private DBContext context = new DBContext("Data source=isostore:/names2.sdf");
    private ObservableCollection<NameTable> nameCollection;

    public ObservableCollection<NameTable> NameCollection
    {
        get
        {
            return nameCollection;
        }
        set
        {
            if (nameCollection != value)
            {
                nameCollection = value;
                NotifyPropertyChanged();
            }
        }
    }

    public void AddNewNameSecondWay(string s)
    {
        NameTable t = new NameTable() { Name = s };
        context.NameDatabaseTable.InsertOnSubmit(t);
        context.SubmitChanges();
        LoadFromDB();
    }

    public void AddNewNameFirstWay(string s)
    {
        NameTable t = new NameTable() { Name = s };
        context.NameDatabaseTable.InsertOnSubmit(t);
        context.SubmitChanges();
        NameCollection.Add(t);
    }

    public void LoadFromDB()
    {
        var query = from i in context.NameDatabaseTable
                    select i;
        NameCollection = new ObservableCollection<NameTable>(query);
    }


    private void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMemberName]string propertyName = null)
    {
        var tmp = PropertyChanged;
        if (tmp != null)
            tmp(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

这是我的XAML绑定代码

<ListBox ItemsSource="{Binding NameCollection, Mode=OneWay}" >
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name, Mode=OneWay}" />
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

在我看来,第二种方法不起作用,因为ObservableCollection内存引用发生了变化。如果这是正确的,如何正确更新绑定?

我使用第二种方法的原因是,我想确保所有数据库约束对于我插入的值都是正确的。

2 个答案:

答案 0 :(得分:0)

您需要通知有关属性的更改。尝试使用Framework 4.0的方法,

Mode=OneWayToSource,UpdateSourceTrigger=PropertyChanged

希望它有所帮助...

答案 1 :(得分:0)

如果您想要了解集合中的更改通知,请调用OnPropertyChanged:

OnPropertyChanged("NameCollection")

您的ViewModel:

public class ViewModel: INotifyPropertyChanged
{
    private DBContext context = new DBContext("Data source=isostore:/names2.sdf");
    private ObservableCollection<NameTable> nameCollection;

    public ObservableCollection<NameTable> NameCollection
    {
        get
        {
            return nameCollection;
        }
        set
        {
            if (nameCollection != value)
            {
                nameCollection = value;
                OnPropertyChanged("NameCollection");
            }
        }
    }

    public void AddNewNameSecondWay(string s)
    {
       // your code
       OnPropertyChanged("NameCollection");
    }


    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
       PropertyChangedEventHandler handler = PropertyChanged;
       if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}