GacUI在結束了文本框的介紹之后,開始進入列表的介紹。列表內容豐富,包含各種預定義的列表控件、用來顯示和操作大量對象的虛擬模式、MVC分離、修改列表樣式等內容。今天先從文本列表的簡單操作開始。這個Demo展示了如何對列表進行添加和刪除。窗口里面有一個列表,然后有添加和刪除兩個按鈕,分別用于把文本框的內容添加到列表內,和刪除掉選中的列表項的。在這個Demo里面只允許列表項單選,并且水平滾動條默認不出現。先看圖:

空間如何布局,我就不再贅述了,明顯是一個四行三列的表格。代碼如下:
#include "..\..\Public\Source\GacUIIncludes.h"
#include <Windows.h>
// for SortedList, CopyFrom and Select
using namespace vl::collections;
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int CmdShow)
{
return SetupWindowsDirect2DRenderer();
}
class NameEditorWindow : public GuiWindow
{
private:
GuiTextList* listBox;
GuiSinglelineTextBox* textBox;
GuiButton* buttonAdd;
GuiButton* buttonRemove;
void buttonAdd_Clicked(GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
// add the specified name at the end of the list box
listBox->GetItems().Add(textBox->GetText());
textBox->SelectAll();
textBox->SetFocus();
}
void buttonRemove_Clicked(GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
// remove the selected items using item index
listBox->GetItems().RemoveAt(listBox->GetSelectedItems()[0]);
}
void listBox_SelectionChanged(GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
// disable the button if no item is selected
buttonRemove->SetEnabled(listBox->GetSelectedItems().Count()>0);
}
public:
NameEditorWindow()
:GuiWindow(GetCurrentTheme()->CreateWindowStyle())
{
this->SetText(L"Controls.ListBox.NameEditor");
GuiTableComposition* table=new GuiTableComposition;
table->SetRowsAndColumns(4, 3);
table->SetCellPadding(3);
table->SetAlignmentToParent(Margin(0, 0, 0, 0));
table->SetRowOption(0, GuiCellOption::MinSizeOption());
table->SetRowOption(1, GuiCellOption::MinSizeOption());
table->SetRowOption(2, GuiCellOption::MinSizeOption());
table->SetRowOption(3, GuiCellOption::PercentageOption(1.0));
table->SetColumnOption(0, GuiCellOption::PercentageOption(1.0));
table->SetColumnOption(1, GuiCellOption::MinSizeOption());
table->SetColumnOption(2, GuiCellOption::MinSizeOption());
this->GetContainerComposition()->AddChild(table);
{
GuiCellComposition* cell=new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(0, 0, 4, 1);
listBox=g::NewTextList();
listBox->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
listBox->SetHorizontalAlwaysVisible(false);
listBox->SelectionChanged.AttachMethod(this, &NameEditorWindow::listBox_SelectionChanged);
cell->AddChild(listBox->GetBoundsComposition());
}
{
GuiCellComposition* cell=new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(0, 1, 1, 1);
GuiLabel* label=g::NewLabel();
label->SetText(L"Name to add: ");
label->GetBoundsComposition()->SetAlignmentToParent(Margin(0, -1, 0, 0));
cell->AddChild(label->GetBoundsComposition());
}
{
GuiCellComposition* cell=new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(0, 2, 1, 1);
textBox=g::NewTextBox();
textBox->GetBoundsComposition()->SetPreferredMinSize(Size(120, 23));
textBox->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
cell->AddChild(textBox->GetBoundsComposition());
}
{
GuiCellComposition* cell=new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(1, 1, 1, 2);
buttonAdd=g::NewButton();
buttonAdd->SetText(L"Add");
buttonAdd->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
buttonAdd->Clicked.AttachMethod(this, &NameEditorWindow::buttonAdd_Clicked);
cell->AddChild(buttonAdd->GetBoundsComposition());
}
{
GuiCellComposition* cell=new GuiCellComposition;
table->AddChild(cell);
cell->SetSite(2, 1, 1, 2);
buttonRemove=g::NewButton();
buttonRemove->SetText(L"Delete");
buttonRemove->SetEnabled(false);
buttonRemove->GetBoundsComposition()->SetAlignmentToParent(Margin(0, 0, 0, 0));
buttonRemove->Clicked.AttachMethod(this, &NameEditorWindow::buttonRemove_Clicked);
cell->AddChild(buttonRemove->GetBoundsComposition());
}
// set the preferred minimum client size
this->GetBoundsComposition()->SetPreferredMinSize(Size(480, 480));
// 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();
}
};
void GuiMain()
{
GuiWindow* window=new NameEditorWindow;
GetApplication()->Run(window);
delete window;
}
這里需要注意的幾點就是,為了實現在列表沒有選中內容的時候禁用刪除按鈕,我們需要監聽GuiTextList::SelectionChanged事件。核心的代碼就是下面這幾行:
void buttonAdd_Clicked(GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
// add the specified name at the end of the list box
listBox->GetItems().Add(textBox->GetText());
textBox->SelectAll();
textBox->SetFocus();
}
void buttonRemove_Clicked(GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
// remove the selected items using item index
listBox->GetItems().RemoveAt(listBox->GetSelectedItems()[0]);
}
void listBox_SelectionChanged(GuiGraphicsComposition* sender, GuiEventArgs& arguments)
{
// disable the button if no item is selected
buttonRemove->SetEnabled(listBox->GetSelectedItems().Count()>0);
}
GuiTextList控件的GetItems函數返回所有的列表項。這個對象有Add、Insert、Clear、IndexOf、Remove、RemoveAt、Contains、Count等函數,可以用來操作列表項。GuiTextList還有GetSelectedItems函數(其實是定義在GuiSelectableListControl里面的),可以用來獲得所有選中的列表項的下標(從0開始)。每當列表內容被修改的時候,GetSelectedItems的結果就會被自動清空。
下一個Demo將是關于如何處理允許多選的列表的操作方法。
posted on 2012-05-23 04:42
陳梓瀚(vczh) 閱讀(2346)
評論(4) 編輯 收藏 引用 所屬分類:
GacUI