【问题标题】:ItemContainerGenerator.ContainerFromIndex returns null after InsertItemContainerGenerator.ContainerFromIndex 插入后返回 null
【发布时间】:2013-04-12 17:28:19
【问题描述】:

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

我的数据源是

var items = new ObservableCollection<string>();
for (int i = 0; i < 10; ++i)
{
    items.Add("Item " + i);
}
lb.ItemsSource = items;

我有一个代码可以为 ListBox 中的每个 ListBoxItem 添加一个 RenderTransform

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
}

它工作正常。问题是我首先需要在列表中插入和项目。当我在 for 循环之前调用 items.Insert(index,"test") 时,我得到一个异常,即当 i==index 时该项目为空。插入新项目时无关紧要,该项目总是为空。

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

编辑:我提取代码并将其放入解决方案中:https://dl.dropboxusercontent.com/u/73642/PhoneApp2.zip。我首先将一个假项目插入到新解决方案中,然后将其淡出并使用动画将原始项目移动到该位置。

【问题讨论】:

  • I have a code to add a RenderTransform to each ListBoxItem in the ListBox 你应该在 XAML 中这样做。这就是 XAML 的用途。非常不鼓励在基于 XAML 的技术中使用过程代码操作 UI 元素或其属性,并且会引入此类错误以及各种可维护性问题。
  • 我不这么认为。有绑定时如何在 XAML 中设置 ListBoxItem 的 Name 或 RenderTransform?
  • 你要这个名字干什么?? RenderTransform 可以使用 Style TargetType="ListBoxItem" 应用。
  • 我有一个 StoryBoard 引用了 2 个项目的名称,这些项目应该使用动画进行切换。所以我想迭代这些项目,将这两个名称设置为这些项目并运行 StoryBoard
  • 发布您的完整代码和 XAML。否则都是猜测。

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


【解决方案1】:

在添加项目后,由于 UI 子系统的异步特性,不会立即生成容器。尝试订阅 ItemsChanged(或 StatusChanged,抱歉我不记得了)并在使用正确的事件参数触发事件时获取项目。

【讨论】:

  • 我遇到了同样的问题。那么,答案是什么事件?
【解决方案2】:

等待 Dispatcher 完成它正在做的事情,例如(由于添加了新项目而更新 UI)

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

如果您曾经在 UI 未更新的情况下操作 UI,例如将项目添加到列表框,您将无法运行针对该 UI 的代码。

编辑:这是您的项目开始工作的代码

 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();
        });

    }

【讨论】:

  • 据我所知,文件后面的代码是在UI线程上执行的
  • 是的,但是直到代码运行和调度程序运行之后,UI 才更新更改。
  • 将我在 for 循环中发布的代码一直包裹到 sbListBox.Begin() 并观看魔术。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-27
  • 2015-11-30
  • 2017-07-03
  • 2022-01-24
  • 2021-11-30
  • 1970-01-01
相关资源
最近更新 更多