从后台线程通知CRUD的ListBox和ListBox项

时间:2013-06-17 17:12:38

标签: sql wpf linq windows-phone-8

我正在使用WP8应用程序中的LINQ / SQL来管理ListBox中显示的项目集合。 有时,使用另一个DataContext的长时间运行操作会更改这些对象。 这些更改可能是CRUD操作之一,因此也可以在后台创建对象。

在iOS中有NSFetchedResultsController,或者我可以使用NSNotification - 我正在搜索类似的内容。

更新更新案例的一些代码

我正在拿这样的物品:

    void loadData() {
        var items = from r in itemDB.items orderby r.UpdatedAt descending select r;
        var Items = new ObservableCollection<Item>(items);
        lstData.ItemsSource = Items;
    }

我的listBox看起来像这样

        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid Margin="10" >
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <TextBox Text="{Binding LocalState}" />
                </Grid>
            </DataTemplate>   
        </ListBox.ItemTemplate>
    </ListBox>

我的背景代码如下:

static public void UploadAll() {



        ThreadPool.SetMaxThreads(1,1);

        ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));

    }

    static void ThreadProc(Object stateInfo)
    {
        ItemsContext itemsDB = new ItemsContext(ItemsContext.DBConnectionString);

        var notUploadedItems = (from i in itemsDB.items
                                    where !i.LocalState.Equals("server")
                                    select i);

        var Items = new ObservableCollection<Item>(notUploadedItems);
        foreach (Item a in Items)
        {
            a.Save(() =>
            {
                Deployment.Current.Dispatcher.BeginInvoke(delegate
                {
                    a.LocalState = "server";
                    itemsDB.SubmitChanges();


                });

                //NOW THE LISTBOX SHOULD BE UPDATED
            }, (err) =>
            {

            });
        }


    }

//NOW THE LISTBOX SHOULD BE UPDATED评论中,应更新相应的列表框模板

添加/删除案例类似。

欢呼声。

1 个答案:

答案 0 :(得分:0)

要直截了当,每次数据更改时创建ObservableCollection的新实例,然后将其重新分配给ItemSource,不仅忽视ObservableCollection的核心目的},它也打破/滥用Data Binding的概念。

//this is the line I am talking about:
var Items = new ObservableCollection<Item>(notUploadedItems);

相反,请创建ObserbaleCollection一次 - 将其设为属性:

private readonly ObservableCollection<Item> _items = new ObservableCollection<Item>();
public ObservableCollection<Item> Items {get {return _items;}

对于更新,请使用集合的'.Add()'或'Remove()'方法

你是正确的,你必须在UI主线程上进行更新:

  DoItOnUIThread(() =>Items.Add(newItem));

   //here's a sample of method that would take any action and execute it on UI thread..
   private void DoItOnUIThread(Action action)
    {
        if (_dispatchService == null) 
           _dispatchService = ServiceLocator.Current.GetInstance<IDispatchService>();

        if (_dispatchService.CheckAccess())
            action.Invoke ();
        else
            _dispatchService.Invoke(action);
    }

让可观察集合完成其工作,通过绑定新项目及其属性更改自动更新UI。如果所有连接/完成正确的列表框不需要在cs代码中更新。