何时将数据加载到 ListBox 的最佳实践 [英] Best practice of when to load data into a ListBox

查看:23
本文介绍了何时将数据加载到 ListBox 的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

WPF/VC++ (C++/cx) - Visual Studio 2013

WPF/VC++ (C++/cx) - Visual Studio 2013

所以我有一个用我创建的 UserControl 填充的 ListBox.每次换页都会丢失数据,很可惜.所以我可以选择在每次加载页面时将数据加载到 ListBox 中,或者在页面之间传递数据.他们每个人都有自己的优点和缺点,但有没有更喜欢的做法?

So I have a ListBox thats populated with a UserControl I've created. Every time the page changes the data is lost, which is unfortunate. So I have the option of loading the data into the ListBox every time the page is loaded or passing the data around from page to page. They each have their own advantage and disadvantage but is there a practice that is preferred?

我想需要考虑的是 ListBox 中有多少个 UserControl,这可能是一个很大的数量(大为 10000+),以及数据是如何存储的.现在我将数据存储在 AVLTree 中,主要用于组织,以便不需要进行排序.只有 10 个页面,其中 6 个页面通常会被导航到(其中 4 个页面是很少使用或仅使用一次的菜单页面),因此数据不必经常从页面传递到页面.每个数据节点的大小只有大约 1 mb,所以不是很大,但足够大,可以在您开始超过 10000 个条目时产生影响(这可能被认为是一种罕见的情况).

I suppose the things to think about would be how many of the UserControls are in the ListBox, which could be a large amount (large being 10000+), and how the data is stored. For now I'm storing the data in a AVLTree, mostly for the organization so that sorting doesn't need to be done. There's only 10 pages, 6 of which would normally be navigated to (4 of them being pages that are menus that are rarely used or only used once) so the data wouldn't have to be passed from page to page often. The size of each data node is only about ~1mb, so not very large but large enough to make a difference as you start getting past 10000 entries (which could be considered a rare circumstance).

我来自游戏编程,所以速度和效率是主要目标.

I come from game programming so speed and efficiency is a primary goal.

是的,这是一个主观问题,但在专业人士或一般编程社区中可能会有首选方法.

Yes, it is a subjective question, however it is possible for there to be a preferred method among professionals or the general programming community.

推荐答案

没有更多的背景信息,也没有关于你在做什么的细节(因为你不能发布任何代码或截图),我只能告诉你什么是WPF 心态背后的基本思想.

Without any more background information, nor details about what you're doing (since you can't post any code or screenshots), I can only tell you what's the basic idea behind The WPF Mentality.

WPF 与我听说过的几乎所有其他 UI 框架都非常不同,因为它确实旨在用于以数据为中心的开发.

WPF is really different from pretty much any other UI frameworks I've heard of, in the sense that it is really intended to be used for Data-Centric development.

从头开始,WPF 主要基于 数据绑定.这消除了大约 95% 的通过程序代码对 UI 进行任何操作的需要.

From the ground up, WPF is largely based on DataBinding. This eliminates in like 95% the need to do any manipulations of the UI via procedural code.

举个简单的例子,假设你有一个 Person 类,它包含 string LastNamestring FirstName 属性:

As a simple example, say you have a Person class which contains string LastName and string FirstName properties:

public class Person
{
    public string LastName {get;set;}
    public string FirstName {get;set;}
}

而不是像这样编写过程代码隐藏来回传递数据值到 UI:

Instead of passing data values back and forth to the UI by writing procedural code-behind like this:

//Traditional approach, Don't use this in WPF.
this.txtLastName.Text = person.LastName;
this.txtFirstName.Text = person.FirstName;
//...
person.LastName = this.txtLastName.Text;
person.FirstName = this.txtFirstName.Text;

您只需在 XAML 中定义一个DataBinding,声明性地:

you simply define a DataBinding in XAML, declaratively:

<TextBox Text="{Binding LastName}"/>
<TextBox Text="{Binding FirstName}"/>

然后设置 UI 的 DataContext 到相关的数据实例:

and then set the UI's DataContext to a relevant instance of data:

//Window constructor example
public MainWindow()
{
    InitializeComponent();
    DataContext = new Person();
}

这种方法有以下优点:

  • 它清楚地将 UI 与数据分离,由于这些层的独立性.您可以在 UI 中放置任何内容,而无需更改应用逻辑/业务逻辑中的任何一行代码.
  • 它减少了样板,因为 WPF 负责传递数据 双向(数据<=> UI).
  • 它允许采用基于属性的方法(而不是基于事件的方法).例如,不需要处理 TextBox.TextChanged 事件之类的事情.WPF 负责在需要时将 Text 值从示例中的 TextBox 传递到基础数据对象.
  • 无需在可视化树中导航.WPF 可视化树 是一个非常复杂的结构,它具有复杂的状态变化和复杂的转换以及复杂的生命周期.您真的不想为了填充几个文本框"而不得不处理这个问题.
  • 在处理集合时,它有助于利用 WPF 的 UI 虚拟化 以自然的方式提供功能(您实际上不必执行默认情况下启用的任何操作).这会在执行方面带来巨大的性能提升时间和内存消耗.
  • 最后但并非最不重要的是,它允许采用声明式方法,而不是传统的命令式方法.您只需定义数据,然后编写业务逻辑(通常以命令式形式),然后定义 UI 及其通过数据绑定与数据的关系.立>
  • it clearly Separates UI from Data, allowing a huge amount of scalability due to the independence of these layers. You can put literally ANYTHING in the UI without having to change a single line of code from your application logic / business logic.
  • It reduces boilerplate because WPF takes care of passing data In Both Directions (Data <=> UI).
  • It allows for a property-based approach (as opposed to an event-based one). For example, there is no need for things like handling the TextBox.TextChanged event. WPF takes care of passing the Text value from the TextBoxes in the example to the underlying Data Object when needed.
  • It removes the need to navigate the Visual Tree. The WPF Visual Tree is a really complex structure, which has complex state changes and complex transitions and a complex lifecycle. You really Don't want to have to deal with that in order to, say, "populate a couple of TextBoxes".
  • When dealing with Collections, it helps leverage WPF's UI Virtualization capabilities in a natural way (you don't actually have to do anything it's enabled by default). This causes a Huge Performance Gain both in terms of execution time and memory consumption.
  • Last but not least, it allows for a Declarative approach, as opposed to the traditional Imperative one. You simply Define your data, then you write your business logic (as usual in an imperative form), then Define the UI and it's relations to the data via DataBinding.

With ListBoxes、ComboBoxes、Menus、TabControls、DataGrids 和所有 ItemsControl完全一样:

With ListBoxes, ComboBoxes, Menus, TabControls, DataGrids, and ALL ItemsControls it's exactly the same:

您不会使用 UserControls 填充 ListBox",而是:

You don't "populate a ListBox with UserControls", instead:

  • 您创建了一个适当的 ViewModel,其中包含一个 IEnumerable<;T> 保存您的数据项.ObservableCollection 是首选,因为 WPF 侦听它的 CollectionChanged 事件并在从集合中添加/删除项目时相应地更新 UI:

  • you create a proper ViewModel which contains an IEnumerable<T> which holds your data items. The ObservableCollection<T> is preferred because WPF listens to it's CollectionChanged event and updates the UI accordingly when items are added/removed from the collection:

public class MyViewModel
{
    public ObservableCollection<Person> People {get;set;}

    //Constructor
    public MyViewModel()
    {
       People = new ObservableCollection<Person>();

       //populate the collection here...
    }
}

  • 然后您定义列表框在XAML中并使用WPF的数据模板 功能,用于定义 UI 对于每个模板的外观项目:

  • Then you Define the ListBox In XAML and use WPF's Data Templating capabilities to Define how the UI will look like for each item:

    <ListBox ItemsSource="{Binding People}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBox Text="{Binding LastName}"/>
                    <TextBox Text="{Binding FirstName}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox> 
    

    注意:如果您想使用 UserControl 在那里代替:

            <DataTemplate>
                <my:MyUserControl/>
            </DataTemplate>
    

  • 最后将 UI 的 DataContext 设置为 ViewModel 的一个实例:

  • And finally set the UI's DataContext to an instance of the ViewModel:

    //Window Constructor
    public MainWindow()
    {
         InitializeComponent();
         DataContext = new MyViewModel();
    }
    

  • 注意:我提到了 INotifyPropertyChanged评论里的界面.此接口必须由您的数据项或视图模型以支持双向绑定适当地.否则 WPF 无法知道"特定属性何时(例如 LastName)已更改并相应地更新 UI.一世认为该主题超出了本答案的范围,并且所以我不会进入它.您可以阅读链接的材料,并且网络上也有大量关于它的材料.

    Note: I mentioned the INotifyPropertyChanged interface in the comments. this interface must be implemented by your Data Items or ViewModels in order to support Two-way Binding properly. Otherwise WPF has no way to "know" when a specific property (such as LastName) is changed and update the UI accordingly. I consider that topic to be out of the scope of this answer and therefore I won't get into it. You can read the linked material, and there is also plenty of material in the Web about it.

    正如我已经提到的,我完全没有 C++ 方面的经验,因此所有这些示例都是用 C# 编写的.请记住,我还提到 WPF 仅支持到 .Net 对象 的数据绑定,我认为它不支持较低级别的内存结构,例如您可能在 C++ 中构造的结构.

    As I already mentioned, I have no experience at all in C++, therefore all these examples are in C#. Remember I also mentioned WPF only supports databinding to .Net Objects, and I don't think it supports lower-level in-memory structures such as the ones you may construct in C++.

    我的建议是,您将 C# 用于软件的上层 UI 部分,而将 C++ 用于您可能需要的任何较低层操作.

    My suggestion is that you use C# for the upper-level UI-facing part of your software, while leaving C++ for any lower-level operations you might need.

    我强烈建议通读这篇文章中链接的材料,最重要的是 Rachel 的 WPF Mentality 和与 ItemsControl 相关的材料.

    I strongly suggest reading thru the material linked in this post, most importantly Rachel's WPF Mentality and the ItemsControl-related material.

    这篇关于何时将数据加载到 ListBox 的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆