• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-341  評論-2670  文章-0  trackbacks-0
                GacUI的所有列表控件都支持虛擬模式。虛擬模式是一種不需要為每一個列表項分配內存的一種顯示方法。在開始的時候,需要高速列表一共有多少個列表項。之后,列表控件在渲染的時候,會跟數據源要求獲取某一個下標所包含的數據,并且在這個數據一直處于屏幕上的時候,只會跟數據源獲取一次。完整的代碼可以在http://www.gaclib.net/Demos/Controls.ListBox.VirtualMode/Demo.html看到。先上圖:



                先看創建界面的代碼。一般來說,所有可以隨著窗口的變化自動排版的控件組織方法,都是使用一個或多個GuiTableComposition來實現的。

            class VirtualModeWindow : public GuiWindow
            {
            private:
                GuiVirtualTextList
            *                    listBox;
                GuiButton
            *                            buttonIncrease;
                GuiButton
            *                            buttonDecrease;
                DataSource
            *                            dataSource;
                
                
            void buttonIncrease_Clicked(GuiGraphicsComposition* sender, GuiEventArgs& arguments)
                {
                    dataSource
            ->SetCount(dataSource->Count()+100000);
                }

                
            void buttonDecrease_Clicked(GuiGraphicsComposition* sender, GuiEventArgs& arguments)
                {
                    dataSource
            ->SetCount(dataSource->Count()-100000);
                }
            public:
                VirtualModeWindow()
                    :GuiWindow(GetCurrentTheme()
            ->CreateWindowStyle())
                {
                    
            this->SetText(L"Controls.ListBox.VirtualMode");

                    GuiTableComposition
            * table=new GuiTableComposition;
                    table
            ->SetRowsAndColumns(32);
                    table
            ->SetCellPadding(3);
                    table
            ->SetAlignmentToParent(Margin(0000));

                    table
            ->SetRowOption(0, GuiCellOption::MinSizeOption());
                    table
            ->SetRowOption(1, GuiCellOption::MinSizeOption());
                    table
            ->SetRowOption(2, GuiCellOption::PercentageOption(1.0));

                    table
            ->SetColumnOption(0, GuiCellOption::PercentageOption(1.0));
                    table
            ->SetColumnOption(1, GuiCellOption::MinSizeOption());

                    
            this->GetContainerComposition()->AddChild(table);
                    
                    {
                        GuiCellComposition
            * cell=new GuiCellComposition;
                        table
            ->AddChild(cell);
                        cell
            ->SetSite(0031);

                        dataSource
            =new DataSource;
                        listBox
            =new GuiVirtualTextList(GetCurrentTheme()->CreateTextListStyle(), GetCurrentTheme()->CreateTextListItemStyle(), dataSource);
                        listBox
            ->GetBoundsComposition()->SetAlignmentToParent(Margin(0000));
                        listBox
            ->SetHorizontalAlwaysVisible(false);
                        cell
            ->AddChild(listBox->GetBoundsComposition());
                    }
                    {
                        GuiCellComposition
            * cell=new GuiCellComposition;
                        table
            ->AddChild(cell);
                        cell
            ->SetSite(0111);

                        buttonIncrease
            =g::NewButton();
                        buttonIncrease
            ->SetText(L"Increase 100000 Items");
                        buttonIncrease
            ->GetBoundsComposition()->SetAlignmentToParent(Margin(0000));
                        buttonIncrease
            ->Clicked.AttachMethod(this&VirtualModeWindow::buttonIncrease_Clicked);
                        cell
            ->AddChild(buttonIncrease->GetBoundsComposition());
                    }
                    {
                        GuiCellComposition
            * cell=new GuiCellComposition;
                        table
            ->AddChild(cell);
                        cell
            ->SetSite(1111);

                        buttonDecrease
            =g::NewButton();
                        buttonDecrease
            ->SetText(L"Decrease 100000 Items");
                        buttonDecrease
            ->GetBoundsComposition()->SetAlignmentToParent(Margin(0000));
                        buttonDecrease
            ->Clicked.AttachMethod(this&VirtualModeWindow::buttonDecrease_Clicked);
                        cell
            ->AddChild(buttonDecrease->GetBoundsComposition());
                    }

                    
            // set the preferred minimum client size
                    this->GetBoundsComposition()->SetPreferredMinSize(Size(480480));
                    
            // call this to calculate the size immediately if any indirect content in the table changes
                    
            // so that the window can calcaulte its correct size before calling the MoveToScreenCenter()
                    this->ForceCalculateSizeImmediately();
                    
            // move to the screen center
                    this->MoveToScreenCenter();
                }
            };

                GuiVirtualTextList就是只有虛擬模式的GuiTextList。事實上GuiVirtualTextList是GuiTextList的基類,而GuiTextList.GetItems()返回的對象也是一個數據源。因此非虛擬模式其實也是通過虛擬模式來實現的。在數據比較少的時候,非虛擬模式操作起來十分的簡單,而在數據比較多的時候,虛擬模式可以帶來很好的性能。上面的代碼創建了一個DataSource類來做數據源,并且有一個SetCount的函數用來更改列表里面的數量的總量,然后每一個列表項的內容都是Item xxx。這是怎么做到的呢?我們來看數據源的代碼:

            class DataSource : public list::ItemProviderBase, private list::TextItemStyleProvider::ITextItemView
            {
            protected:
                
            int                count;
            public:
                DataSource()
                    :count(
            100000)
                {
                }

                
            void SetCount(int newCount)
                {
                    
            if(0<=newCount)
                    {
                        
            int oldCount=count;
                        count
            =newCount;
                            
                        
            // this->InvokeOnItemModified(affected-items-start, affected-items-count, new-items-count);
                        
            // this function notifies the list control to update it's content and scroll bars
                        if(oldCount<newCount)
                        {
                            
            // insert
                            this->InvokeOnItemModified(oldCount, 0, newCount-oldCount);
                        }
                        
            else if(oldCount>newCount)
                        {
                            
            // delete
                            this->InvokeOnItemModified(newCount, oldCount-newCount, 0);
                        }
                    }
                }

                
            // GuiListControl::IItemProvider

                
            int Count()
                {
                    
            return count;
                }

                IDescriptable
            * RequestView(const WString& identifier)
                {
                    
            if(identifier==list::TextItemStyleProvider::ITextItemView::Identifier)
                    {
                        
            return this;
                    }
                    
            else if(identifier==GuiListControl::IItemPrimaryTextView::Identifier)
                    {
                        
            return this;
                    }
                    
            else
                    {
                        
            return 0;
                    }
                }

                
            void ReleaseView(IDescriptable* view)
                {
                }

                
            // list::TextItemStyleProvider::ITextItemView

                WString GetText(
            int itemIndex)
                {
                    
            return L"Item "+itow(itemIndex+1);
                }

                
            bool GetChecked(int itemIndex)
                {
                    
            // DataSource don't support check state
                    return false;
                }

                
            void SetCheckedSilently(int itemIndex, bool value)
                {
                    
            // DataSource don't support check state
                }

                
            // GuiListControl::IItemPrimaryTextView

                WString GetPrimaryTextViewText(
            int itemIndex)
                {
                    
            return GetText(itemIndex+1);
                }

                
            bool ContainsPrimaryText(int itemIndex)
                {
                    
            return true;
                }
            };

                對于GuiVirtualTextList來說,只需要實現vl::presentation::controls::list::TextItemStyleProvider::ITextItemView就可以了。GacUIIncludes.h里面已經有了using namespace vl::presentation::controls,所以在這里只需要從list::開始寫。list::TextItemStyleProvider::ITextItemView還要求實現GuiListControl::IItemPrimaryTextView。在目前的GacUI里面,IItemPrimaryTextView是專門為下拉框準備的。因為下拉框允許接受任何一種列表對象當做下拉內容,所以GacUI的列表數據源默認都要求實現IItemPrimaryTextView。

                實現數據源的時候,其實并不要求數據源類繼承自ITextItemView和IItemPrimaryTextView。因為GacUI都是通過RequestView來獲取一個View的接口指針的,代碼如上。實現這兩個View也很簡單,在這里就不贅述了。

                GuiTextList就介紹到這里了,接下來的幾個Demo都將是關于ListView的。下一個Demo是ListView山寨Windows 7的資源管理器界面,可以在http://www.gaclib.net/Demos/Controls.ListView.ViewSwitching/Demo.html看到。具體內容將在下一篇博客中闡述。
            posted on 2012-05-30 07:19 陳梓瀚(vczh) 閱讀(2477) 評論(1)  編輯 收藏 引用 所屬分類: GacUI

            評論:
            # re: GacUI Demo:列表的虛擬模式,不需要為每一個列表項分配內存的一種顯示方法 2012-05-31 04:37 | 空明流轉
            師祖威武!帥不忍睹!  回復  更多評論
              
            99精品国产免费久久久久久下载| 中文字幕久久欲求不满| 综合久久国产九一剧情麻豆| 久久久www免费人成精品| 久久精品国产亚洲av影院| 国产精品久久国产精品99盘| 久久久久久久久久免免费精品| 久久国产亚洲精品| 999久久久国产精品| 久久久这里有精品| 久久久久久久99精品免费观看| 一本综合久久国产二区| 99精品久久精品| 久久综合亚洲鲁鲁五月天| 热99re久久国超精品首页| 思思久久精品在热线热| 午夜不卡888久久| 亚洲国产另类久久久精品| 久久久精品日本一区二区三区 | 久久久久久国产精品美女 | 久久久91人妻无码精品蜜桃HD | 久久一本综合| 97久久精品无码一区二区天美| 亚洲а∨天堂久久精品9966| 久久精品国产亚洲av水果派 | 久久99热这里只有精品国产| 99re久久精品国产首页2020| 久久精品青青草原伊人| 久久亚洲电影| 久久久无码精品亚洲日韩软件| 99久久er这里只有精品18| 人妻无码精品久久亚瑟影视 | 日本福利片国产午夜久久| 99久久er这里只有精品18| 亚洲精品无码成人片久久| 国内精品久久久久影院薰衣草 | 日韩亚洲欧美久久久www综合网| 久久精品亚洲中文字幕无码麻豆| 久久亚洲精品中文字幕| 亚洲国产精品无码久久久蜜芽| 少妇内射兰兰久久|