在Insert之后,ItemContainerGenerator.ContainerFromIndex返回null

时间:2013-04-12 17:28:20

标签: c# windows-phone-7 xaml windows-phone-8

我在Windows Phone应用中有一个ListBox。在按钮操作中,我需要在名为ListBoxItem的{​​{1}}中的每个ListBox上设置转换和名称。

我的数据源是

lb

我有一个代码可以向ListBox中的每个var items = new ObservableCollection<string>(); for (int i = 0; i < 10; ++i) { items.Add("Item " + i); } lb.ItemsSource = items; 添加RenderTransform

ListBoxItem

它运作正常。问题是我首先需要插入项目到列表。当我在for循环之前调用for (int i = 0; i < items.Count;++i ) { var item = this.lb.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem; item.RenderTransform = new CompositeTransform(); item.Name = i.ToString() //needed for storybord //another stuff } 时,我得到一个异常,即items.Insert(index,"test")时该项为空。插入新项目无关紧要,我总是为该项目获取null。

我做错了什么?或者在我尝试访问i==index之前插入新项目时是否需要等待ListBox的事件?

修改:我提取了代码并将其放入解决方案中:https://dl.dropboxusercontent.com/u/73642/PhoneApp2.zip。我首先在新解决方案中插入假物品,将其淡化并使用动画将原始物品移动到该位置。

2 个答案:

答案 0 :(得分:2)

在添加项目之后,由于UI子系统的异步性质,没有生成容器。尝试订阅ItemsChanged(或者StatusChanged,对不起,我不记得),并在事件被触发时使用正确的事件参数获取项目。

答案 1 :(得分:-1)

等待Dispatcher完成其执行的操作(因为添加了新项目而更新UI)

this.Dispatcher.BeginInvoke(() =>
{
   //Code Here
});

如果您操纵用户界面,例如在没有更新用户界面的情况下将项目添加到列表框,您将无法运行定位到用户界面的代码。

编辑:以下是项目开始工作的代码

 private void Button_Click(object sender, RoutedEventArgs e)
    {            
        start = Int32.Parse(from.Text);
        end = Int32.Parse(to.Text);

        fake = items[start];
        //items.Insert(end, fake);

        this.Dispatcher.BeginInvoke(() =>
        {
            for (int i = 0; i < items.Count; ++i)
            {
                var item = this.lb.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem;
                item.Name = i.ToString();
            }


            (this.lb.ItemContainerGenerator.ContainerFromIndex(end) as ListBoxItem).RenderTransform = new CompositeTransform();
            (this.lb.ItemContainerGenerator.ContainerFromIndex(end) as ListBoxItem).Name = "listBoxItem1";


            (this.lb.ItemContainerGenerator.ContainerFromIndex(start) as ListBoxItem).Name = "listBoxItem";

            sbListBox.Begin();
        });

    }