Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows phone 7 windows phone虚拟化画布可实现更高效、更灵活的列表框,这是一种正确的方法吗?_Windows Phone 7_Windows Phone 8_Windows Phone - Fatal编程技术网

Windows phone 7 windows phone虚拟化画布可实现更高效、更灵活的列表框,这是一种正确的方法吗?

Windows phone 7 windows phone虚拟化画布可实现更高效、更灵活的列表框,这是一种正确的方法吗?,windows-phone-7,windows-phone-8,windows-phone,Windows Phone 7,Windows Phone 8,Windows Phone,背景: 我正在开发这个应用程序。其中一页是新闻提要。新闻中的数据是动态的:它可能包含多个文本块、许多图像,并根据内容计算每个新闻项的布局 由于无法(我不知道如何)使其与ListBox/DataTemplate/Binding一起工作,因此我采用了较低级别的方法,并尝试实现虚拟化画布: 想法很简单: 每个包含的项实现: 可虚拟化的公共接口 { void ChangeState(VirtualizableState newState) -面板应放入ScrollViewer并初始化: public

背景: 我正在开发这个应用程序。其中一页是新闻提要。新闻中的数据是动态的:它可能包含多个文本块、许多图像,并根据内容计算每个新闻项的布局

由于无法(我不知道如何)使其与ListBox/DataTemplate/Binding一起工作,因此我采用了较低级别的方法,并尝试实现虚拟化画布:

想法很简单:

每个包含的项实现:

可虚拟化的公共接口 { void ChangeState(VirtualizableState newState)

-面板应放入ScrollViewer并初始化:

public void InitializeWithScrollViewer(ScrollViewer _scrollViewer)
    {
        _listScrollViewer = _scrollViewer;
        EnsureBoundToScrollViewer();
    }

    protected void EnsureBoundToScrollViewer()
    {
        Binding binding = new Binding();
        binding.Source = _listScrollViewer;
        binding.Path = new PropertyPath("VerticalOffset");
        binding.Mode = BindingMode.OneWay;
        this.SetBinding(ListVerticalOffsetProperty, binding);


    }
面板实现了AddItems方法:

公共无效附加项(IEnumerable\u itemstobedded) {

        double topMargin = 0;


        foreach (var itemToBeAdded in _itemsToBeAdded)
        {

            itemToBeAdded.View.Margin = new Thickness(0, itemToBeAdded.Margin.Top + topMargin, 0, 0);

            _virtualizableItems.Add(itemToBeAdded);


            topMargin += itemHeightIncludingMargin;
        }

        Height = topMargin;

    }
然后根据滚动位置的变化加载和卸载项目:

私有void LoadItemsInSegment(段段,虚拟化状态desiredState) {
对于(inti=segment.LowerBound;i我认为您的虚拟化面板不会虚拟化任何东西

在上下文中,虚拟化的工作方式如下。您需要显示10000个数据项。屏幕仅适合15个UI元素。系统提供的VirtualzingStackPanel创建~17个UI元素,在用户滚动列表时重用这些元素。当UI元素离开屏幕时,面板“释放”UI元素(如果需要,可以进行干预,请参见
ClearContainerForItemOverride
方法)。并为以后的重用做好准备(同样,如果需要,可以进行干预,请参见
PrepareContainerForItemOverride
)。如果需要更多元素(例如,因为数据项越来越小),则会创建新的UI元素

关键是你有10000个虚拟物品,而实际物品只有17个,因此虚拟化

然而,在你的代码中,我明白了

public interface IVirtualizable
{
    FrameworkElement View { get; }
}
这意味着您的数据项和UI元素之间存在1对1的关系。UI元素非常昂贵,它们拥有GPU纹理和其他系统资源。这就是为什么添加更多元素时会出现性能问题的原因


重新实现VirtualizingStackPanel很难。它的代码是MyVirtualizingPanel类的3-4倍。幸运的是,您不需要这样做,它已经在框架中,而且功能非常广泛。如果您不喜欢列表框,因为它是选中/未选中的内容,请使用普通ItemsControl,将ItemContainer设置为VirtualizingStackPanel.

谢谢你有意义的回答。我不完全同意你的观点。事实上,我的虚拟化面板没有回收容器,但虚拟化已经到位。IVirtualizable.View(在我所有的IVirtualizable实现中都是画布)只有当相应的元素处于加载状态时,面板才能访问。因此,接口的实现者可以在卸载时将view=null设置为空,并在加载时重新实例化它。我正在识别问题中描述的问题,实际上我倾向于认为我的方法会起作用。将返回结果。
            item.ChangeState(desiredState);

            if (!Children.Contains(item.View))
            {
                Children.Add(item.View);
            }
        }
    }
            item.ChangeState(desiredState);

            if (!Children.Contains(item.View))
            {
                Children.Add(item.View);
            }
        }
    }

 private void UnloadItemsInSegment(Segment segment)
    {
        for (int i = segment.LowerBound; i <= segment.UpperBound; i++)
        {
            var item = _virtualizableItems[i];


            Children.Remove(item.View);

            item.ChangeState(VirtualizableState.Unloaded);

        }
    }
public interface IVirtualizable
{
    FrameworkElement View { get; }
}