Este artigo passo a passo descreve como utilizar um controlo de
caixa de combinação para editar os dados num controlo
ListView . Este método substitui a abordagem da caixa de texto padrão de edição de dados num controlo
ListView .
Obter informações sobre a técnica
Utilizando a propriedade de
LabelEdit do controlo
ListView , pode permitir que o utilizador editar o conteúdo do controlo
ListView . Para editar os dados no controlo
ListView , pode utilizar uma caixa de texto padrão. Ocasionalmente, poderá pretender que outro controlo para editar o controlo. Este artigo descreve como utilizar um controlo de
caixa de combinação para editar os dados num controlo
ListView quando o controlo
ListView está na vista Detalhes.
Quando o utilizador selecciona uma linha no controlo
ListView , um cálculo é efectuado para localizar o rectângulo delimitadora da primeira coluna da linha que o utilizador clicou. Que o cálculo considera que a coluna pode não estar visível ou poderá não ser totalmente visível quando o utilizador clique na linha e quando o controlo de
caixa de combinação é dimensionado e é apresentado correctamente.
Além de posicionamento e dimensionar o controlo de
caixa de combinação , esta aplicação de exemplo aguarda também duas mensagens seguintes no controlo
ListView :
Estas mensagens ocorrem sempre que o utilizador desloca através do controlo
ListView vertical ou horizontalmente. Uma vez que o controlo de
caixa de combinação não é fisicamente parte do controlo
ListView , o controlo de
caixa de combinação não se automaticamente desloca com o controlo
ListView . Assim, sempre que um destes dois mensagens ocorre, o controlo de
caixa de combinação tem de estar ocultas. Para ver estas mensagens, tem de criar uma classe
UserControl personalizada que herda da classe
ListView . Neste controlo personalizado, o método
WndProc é substituído para permitir a ser verificado para percorrer todas as mensagens.
Nota Não para substituir o
WndProc método, o código e qualquer código que chama-tem de ter geridos permissões de código (
SecurityPermission com o sinalizador
UnmanagedCode especificado).
Criar o controlo ListView herdado
- Inicie o Microsoft Visual Studio .NET 2003 ou Microsoft Visual Studio 2005.
- No menu ficheiro , aponte para Novo e, em seguida, clique em projecto .
- Na caixa de diálogo Novo projecto , clique em Projectos do Visual C++ em Project Types e, em seguida, clique em Windows controlo biblioteca (NET) em modelos .
Nota No Visual Studio 2005, clique em Visual C++ em Project Types e, em seguida, clique em Biblioteca de controlos formulários do Windows em modelos . - Na caixa nome , escreva MyListView . Na caixa localização , escreva c:\teste e, em seguida, clique em OK .
- Substituir todo o código da classe UserControl o seguinte código: # pragma
#pragma once
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
namespace MyListView
{
/// <summary>
/// Summary for MyListViewControl
/// </summary>
///
/// WARNING: If you change the name of this class, you must change the
/// 'Resource File Name' property for the managed resource compiler tool
/// that is associated with all .resx files that this class depends on.
/// Otherwise, the designers cannot interact properly with localized
/// resources that are associated with this form.
public __gc class MyListViewControl : public System::Windows::Forms::ListView
{
public:
MyListViewControl(void)
{
InitializeComponent();
}
protected:
void Dispose(Boolean disposing)
{
if (disposing && components)
{
components->Dispose();
}
__super::Dispose(disposing);
}
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container* components;
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
}
private:
static const int WM_HSCROLL = 0x114;
static const int WM_VSCROLL = 0x115;
protected:
void WndProc(Message *msg)
{
// Look for the WM_VSCROLL or the WM_HSCROLL messages.
if ((msg->Msg == WM_VSCROLL) || (msg->Msg == WM_HSCROLL))
{
// Move focus to the ListView control to cause the ComboBox control to lose focus.
this->Focus();
}
// Pass the message to default handler.
__super::WndProc(msg);
}
};
} Nota tem de adicionar o common language runtime suportam a opção do compilador (/ clr:oldSyntax) no Visual C++ 2005 a compilação com êxito o exemplo de código completo. Para adicionar a opção de compilador do suporte de tempo de execução idioma comum no Visual C++ 2005, siga estes passos: - Clique em Project e, em seguida, clique em <ProjectName> propriedades .
Nota <ProjectName> é um marcador de posição para o nome do projecto. - Expanda Propriedades de configuração e, em seguida, clique em Geral .
- Clique para seleccionar Runtime do idioma comum suporte, sintaxe antigo (/ clr:oldSyntax) na definição de projecto Common Language Runtime suporte no painel da direita, clique em Aplicar e, em seguida, clique em OK .
Para obter mais informações sobre o common language runtime suporte a opção do compilador, visite o seguinte Web site da Microsoft: - Guardar e criar o projecto.
Criar a aplicação de exemplo
- Siga estes passos para criar um novo Windows Forms aplicações no Microsoft Visual C++. NET:
- No menu ficheiro , aponte para Novo e, em seguida, clique em projecto .
- Na caixa de diálogo Novo projecto , clique em Projectos do Visual C++ em Project Types e, em seguida, clique em Aplicações de formulários do Windows (.NET) em modelos .
Nota No Visual Studio 2005, clique em Visual C++ em Project Types e, em seguida, clique em Aplicações de formulários do Windows em modelos . - Na caixa nome , escreva Q816188 e, em seguida, clique em OK . Por predefinição, é criado um formulário é denominado Form1.
- Siga estes passos para adicionar o controlo que criou na secção "Create the inherited ListView
control" deste artigo para a aplicação do Windows:
- No menu Ferramentas , clique em caixa de ferramentas de adicionar/remover itens .
- Na caixa de diálogo Personalizar a caixa de ferramentas , clique no separador de .NET Framework Components e, em seguida, clique em Procurar .
- Na caixa de diálogo Abrir , localize o controlo que criou na secção "Create the
inherited ListView control" e, em seguida, clique em Abrir . Este passo Adiciona este controlo para a caixa de ferramentas dos controlos para que possa utilizar o controlo do mesmo modo para qualquer outro controlo.
- Adicione um controlo MyListView ao Form1 .
- Adicione um controlo ComboBox ao Form1 .
- Na janela Propriedades do controlo de caixa de combinação , defina o valor da propriedade nome como cbListViewCombo e, em seguida, defina a propriedade visível como Falso .
- Adicione o seguinte código à classe do Form1 acima do construtor:
private:
ListViewItem *lvItem;
- Adicione o seguinte código ao evento carregar do Form1 :
// Add some items to the combo box list.
this->cbListViewCombo->Items->Add(S"NC");
this->cbListViewCombo->Items->Add(S"WA");
// Set the view of the ListView control to Details.
this->myListViewControl1->View = View::Details;
// Turn on full row select.
this->myListViewControl1->FullRowSelect = true;
// Add data to the ListView control.
ColumnHeader *columnheader;
ListViewItem *listviewitem;
// Create sample ListView data.
listviewitem = new ListViewItem(S"NC");
listviewitem->SubItems->Add(S"North Carolina");
this->myListViewControl1->Items->Add(listviewitem);
listviewitem = new ListViewItem(S"WA");
listviewitem->SubItems->Add(S"Washington");
this->myListViewControl1->Items->Add(listviewitem);
// Create column headers for the data.
columnheader = new ColumnHeader();
columnheader->Text = S"State Abbreviation";
this->myListViewControl1->Columns->Add(columnheader);
columnheader = new ColumnHeader();
columnheader->Text = S"State";
this->myListViewControl1->Columns->Add(columnheader);
// Loop through and size each column header to fit the column header text.
ColumnHeader *ch;
IEnumerator *ie = this->myListViewControl1->Columns->GetEnumerator();
while (ie->MoveNext())
{
ch = __try_cast<ColumnHeader *> (ie->Current);
ch->Width = -2;
} - Adicione o seguinte código ao evento SelectedValueChanged do controlo de caixa de combinação :
// Set the text of the ListView item to match the ComboBox control.
lvItem->Text = this->cbListViewCombo->Text;
// Hide the ComboBox control.
this->cbListViewCombo->Visible = false;
- Adicione o seguinte código ao evento deixar do controlo de caixa de combinação :
// Set text of the ListView item to match the ComboBox control.
lvItem->Text = this->cbListViewCombo->Text;
// Hide the ComboBox control.
this->cbListViewCombo->Visible = false;
- Adicione o seguinte código ao PremirATecla evento do controlo caixa de combinação :
// Verify that the user presses the ESC key.
switch (e->KeyChar)
{
case (char)(int)Keys::Escape:
{
// Reset the original text value, and then hide the ComboBox control.
this->cbListViewCombo->Text = lvItem->Text;
this->cbListViewCombo->Visible = false;
break;
}
case (char)(int)Keys::Enter:
{
// Hide the ComboBox control.
this->cbListViewCombo->Visible = false;
break;
}
} - Adicione o seguinte código ao SoltarOBotãoDoRato evento do controlo myListViewContro11 :
// Get the item on the row that the user clicks.
lvItem = this->myListViewControl1->GetItemAt(e->get_X(), e->get_Y());
// Make sure that an item the user clicks.
if (lvItem != NULL)
{
// Get the bounds of the item that the user clicks.
Rectangle ClickedItem = lvItem->Bounds;
// Verify that the column is completely scrolled off to the left.
if ((ClickedItem.Left + this->myListViewControl1->Columns->get_Item(0)->Width) < 0)
{
// If the cell is out of view to the left, do nothing.
return;
}
// Verify that the column is partially scrolled off to the left.
else if (ClickedItem.Left < 0)
{
// Determine if the column extends beyond the right side of the ListView control.
if ((ClickedItem.Left + this->myListViewControl1->Columns->get_Item(0)->Width) > this->myListViewControl1->Width)
{
// Set the width of the column to match the width of the ListView control.
ClickedItem.Width = this->myListViewControl1->Width;
ClickedItem.X = 0;
}
else
{
// The right side of the cell is in view.
ClickedItem.Width = this->myListViewControl1->Columns->get_Item(0)->Width + ClickedItem.Left;
ClickedItem.X = 2;
}
}
else if (this->myListViewControl1->Columns->get_Item(0)->Width > this->myListViewControl1->Width)
{
ClickedItem.Width = this->myListViewControl1->Width;
}
else
{
ClickedItem.Width = this->myListViewControl1->Columns->get_Item(0)->Width;
ClickedItem.X = 2;
}
// Adjust the top to account for the location of the ListView control.
ClickedItem.Y += this->myListViewControl1->Top;
ClickedItem.X += this->myListViewControl1->Left;
// Assign calculated bounds to the ComboBox control.
this->cbListViewCombo->Bounds = ClickedItem;
// Set default text for the ComboBox control to match the item that the user clicks.
this->cbListViewCombo->Text = lvItem->Text;
// Display the ComboBox control, and then make sure that it is on top with focus.
this->cbListViewCombo->Visible = true;
this->cbListViewCombo->BringToFront();
this->cbListViewCombo->Focus();
}
Verificar se funciona
- Guarde e, em seguida, execute o exemplo.
- Clique numa linha no controlo ListView .
Repare que uma caixa de combinação é apresentada sobre a localização da primeira coluna da linha actual. - Para ocultar a caixa de combinação, clique num item na caixa de combinação, prima ESC e, em seguida, percorra o controlo ListView ou clique em outro controlo.
Repare que o valor que clicou na caixa de combinação é colocado na primeira coluna da linha seleccionada do controlo ListView .