• <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  評(píng)論-2670  文章-0  trackbacks-0
                GacUI的所有列表控件都支持虛擬模式。虛擬模式是一種不需要為每一個(gè)列表項(xiàng)分配內(nèi)存的一種顯示方法。在開始的時(shí)候,需要高速列表一共有多少個(gè)列表項(xiàng)。之后,列表控件在渲染的時(shí)候,會(huì)跟數(shù)據(jù)源要求獲取某一個(gè)下標(biāo)所包含的數(shù)據(jù),并且在這個(gè)數(shù)據(jù)一直處于屏幕上的時(shí)候,只會(huì)跟數(shù)據(jù)源獲取一次。完整的代碼可以在http://www.gaclib.net/Demos/Controls.ListBox.VirtualMode/Demo.html看到。先上圖:



                先看創(chuàng)建界面的代碼。一般來說,所有可以隨著窗口的變化自動(dòng)排版的控件組織方法,都是使用一個(gè)或多個(gè)GuiTableComposition來實(shí)現(xiàn)的。

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

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

                對(duì)于GuiVirtualTextList來說,只需要實(shí)現(xiàn)vl::presentation::controls::list::TextItemStyleProvider::ITextItemView就可以了。GacUIIncludes.h里面已經(jīng)有了using namespace vl::presentation::controls,所以在這里只需要從list::開始寫。list::TextItemStyleProvider::ITextItemView還要求實(shí)現(xiàn)GuiListControl::IItemPrimaryTextView。在目前的GacUI里面,IItemPrimaryTextView是專門為下拉框準(zhǔn)備的。因?yàn)橄吕蛟试S接受任何一種列表對(duì)象當(dāng)做下拉內(nèi)容,所以GacUI的列表數(shù)據(jù)源默認(rèn)都要求實(shí)現(xiàn)IItemPrimaryTextView。

                實(shí)現(xiàn)數(shù)據(jù)源的時(shí)候,其實(shí)并不要求數(shù)據(jù)源類繼承自ITextItemView和IItemPrimaryTextView。因?yàn)镚acUI都是通過RequestView來獲取一個(gè)View的接口指針的,代碼如上。實(shí)現(xiàn)這兩個(gè)View也很簡單,在這里就不贅述了。

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

            評(píng)論:
            # re: GacUI Demo:列表的虛擬模式,不需要為每一個(gè)列表項(xiàng)分配內(nèi)存的一種顯示方法 2012-05-31 04:37 | 空明流轉(zhuǎn)
            師祖威武!帥不忍睹!  回復(fù)  更多評(píng)論
              
            亚洲精品第一综合99久久| 国产激情久久久久影院老熟女| 久久精品国产第一区二区| 久久国产成人午夜aⅴ影院| 欧美激情一区二区久久久| 亚洲日韩中文无码久久| 国产99久久久国产精免费| 亚洲国产精品无码久久| 国产99久久久国产精品~~牛| 久久99这里只有精品国产| 99久久无码一区人妻a黑| 午夜精品久久久久| 国产99久久久久久免费看| 久久中文骚妇内射| 一本色道久久综合| 国产激情久久久久影院老熟女| 久久久精品2019免费观看| 无码任你躁久久久久久老妇App| 国产精品激情综合久久| 成人免费网站久久久| 日韩精品久久久久久久电影蜜臀 | 国产精品一区二区久久| 欧美性猛交xxxx免费看久久久| 久久中文娱乐网| 国产成人久久精品一区二区三区 | 久久精品国产2020| 亚洲精品国精品久久99热| 欧美日韩中文字幕久久伊人| 99久久精品日本一区二区免费| 中文字幕亚洲综合久久菠萝蜜| 国产综合成人久久大片91| 久久精品www| 999久久久免费国产精品播放| 69国产成人综合久久精品| 久久ZYZ资源站无码中文动漫 | 亚洲中文字幕久久精品无码APP| 久久午夜综合久久| 欧美日韩精品久久免费| 久久精品国产亚洲AV蜜臀色欲 | 久久精品亚洲精品国产欧美| 青青久久精品国产免费看|