PBToolboxAI v5 ← Site

propertygrid — u_pbt_propertygrid #

← Referência dos componentes · Índice do guia

propertygrid é a janela de propriedades de um IDE, para os seus próprios dados: valores com nome, arrumados em categorias que se recolhem, cada um com o editor do seu tipo — texto, número, caixa de verificação, lista de opções, cor, data, palavra-passe. Duas vistas (por categoria, alfabética), uma caixa de pesquisa, um painel de ajuda que descreve a propriedade selecionada e um botão … que abre uma caixa de diálogo sua. O utilizador altera, ue_value_changed diz-lho.

▶ Ver ao vivo — Aplicação de demonstração, mosaico Property grid: a pré-visualização, o código que o produz e esta página, lado a lado.


Em resumo #

Userobjectu_pbt_propertygrid
Classes de itensn_pbt_propertygrid_category (categoria) → n_pbt_propertygrid_property (propriedade)
Serve paraSubstituir um ecrã de definições montado com campos e caixas por um inspetor com tema, tipado e pesquisável: as definições de um documento, de um relatório, de uma ficha, de um objeto da aplicação
ValoresSempre texto, um a um (of_property(endereço).is_value); todos de uma vez e tipados com of_values
Opções opt-inib_veto_changes

Início rápido #

// The settings of a report : one value at the top, then a category
uo_grid.of_add_property(/*keys*/ "title", /*label*/ "Title", /*type*/ u_pbt_propertygrid.TYPE_STRING, /*value*/ "Monthly sales")
uo_grid.of_add_category(/*key*/ "page", /*title*/ "Page")
uo_grid.of_add_property(/*keys*/ "page/landscape", /*label*/ "Landscape", /*type*/ u_pbt_propertygrid.TYPE_BOOLEAN, /*value*/ "true")
uo_grid.of_add_property(/*keys*/ "page/margin", /*label*/ "Margin (mm)", /*type*/ u_pbt_propertygrid.TYPE_NUMBER, /*value*/ "12.5")

// The help pane describes the selected property
uo_grid.of_property(/*keys*/ "page/margin").is_description = "Around the printed area, in [b]millimetres[/b]."
// event ue_value_changed of uo_grid : (string as_keys, string as_value)
// The value is already written ; the address says which one
choose case as_keys
    case "title"
        of_set_report_title(as_value)
    case "page/landscape"
        of_set_landscape(as_value = "true")
end choose

Um endereço por propriedade #

Uma propriedade designa-se pelo seu endereço: a sua chave sozinha no primeiro nível ("title"), a categoria e depois a propriedade unidas por / sob uma categoria ("page/margin"). Uma propriedade expansível (TYPE_GROUP) contém, por sua vez, propriedades, acrescentadas no seu endereço: "appearance/font/size" no grupo font da categoria appearance, "margin/left" num grupo de cima — e um grupo pode conter outro. O que contém uma propriedade é, portanto, uma categoria (um único nível) ou um grupo. Uma categoria designa-se pela sua chave sozinha. No primeiro nível, uma chave nomeia uma única coisa: uma categoria e uma propriedade de cima não a podem partilhar. Os eventos levam o mesmo endereço, o que escreveu.

// A category by its key, a property by its address
uo_grid.of_category(/*key*/ "page").ib_collapsed = true
uo_grid.of_property(/*keys*/ "page/margin").is_value = "15"

// A property held by a group : the address goes through the group
uo_grid.of_property(/*keys*/ "appearance/font/size").is_value = "11"

Os tipos de valor #

O tipo escolhe-se uma vez, em of_add_property, e dá o editor da linha. O valor, esse, é sempre texto — dado, lido, entregue pelos eventos — escrito da mesma forma qualquer que seja a língua do posto.

ConstanteEditorO valor, em texto
TYPE_STRINGCaixa de textoO texto tal como está
TYPE_NUMBERCaixa de texto que só aceita um número, lido na língua de apresentação: o seu separador decimal ou um ponto, o seu agrupamento dos milhares quando bem formado (1,000 vale mil em inglês, 1.500 mil e quinhentos em alemão, 1 234,5 em francês); uma entrada ambígua (1,5 em inglês, 1 2) ou que não seja um número é recusada: o texto digitado fica, emoldurado a vermelho, e o painel de ajuda diz porquê (Esc desiste dele). is_min, is_max e id_step limitam a entrada e regem Cima / BaixoCom ponto: "12.5"; "" = vazio. Mantido algarismo a algarismo ("1.50" continua "1.50"); um texto que não seja um número é recusado
TYPE_BOOLEANCaixa de verificação"true" · "false"
TYPE_ENUMLista de opções com as cores do tema; as suas opções acrescentam-se uma a uma (of_add_option), o seu texto simples, sem etiquetasO valor da opção escolhida, nunca o seu texto
TYPE_COLORAmostra da cor e seletor de cor; a célula mostra r, g, b. Acima de 16777215, uma cor de sistema do PowerBuilder (67108864 Button Face, 553648127 Transparent, 1073741824 Window Background…) é mostrada pelo seu nome, com uma amostra neutra, e o seletor abre-se sem cor atualO long RGB escrito em texto: String(RGB(255, 0, 0)) = "255"
TYPE_DATECalendário; a célula mostra a data no formato da língua de apresentação"yyyy-mm-dd" : String(Today(), "yyyy-mm-dd")
TYPE_PASSWORDCaixa de texto mascaradaO texto simples, nunca mostrado nem encontrado pela pesquisa (mesmo {x:raw} de um resumo continua mascarado)
TYPE_GROUPNenhum: uma propriedade expansível (um tipo de letra, uma margem), com uma seta no início do seu rótulo; contém as propriedades acrescentadas no seu endereço e expande-se com ib_expanded, a sua seta, um duplo clique no seu rótulo ou o teclado. Fechada quando é acrescentadaNenhum a dar ("", qualquer outro é recusado); lido, o seu resumo: o que is_summary escreve, senão os valores mostrados do que contém, ocultos saltados, unidos por ; ("Segoe UI; 9; True"); escrito, ignorado

Um valor que o seu tipo não consegue conter é recusado — em of_add_property (-5) como por is_value ou is_default (o anterior fica) — e of_get_last_error diz porquê: um número que não o é, um booleano diferente de true / false / 1 / 0, uma data que não é um yyyy-mm-dd real, uma cor que não é um inteiro a partir de -1, um TYPE_STRING ou um TYPE_PASSWORD em várias linhas (o campo da grelha tem uma linha). "" (sem valor) é sempre aceite. Um valor de lista que nenhuma opção oferece é aceite, e mostrado tal como está: uma lista pode ser carregada depois do seu valor. A cor -1 — a que o tema dá, a convenção de toda a biblioteca — aparece «(predefinição)»; uma cor de sistema e os true / false de um resumo escrevem-se na língua de apresentação.


Propriedades #

PropriedadeTipoPredefiniçãoFunção
is_sortstring"categorized"A vista: SORT_CATEGORIZED (as propriedades de cima, depois cada categoria sob um cabeçalho que se recolhe) ou SORT_ALPHABETICAL (uma única lista ordenada por rótulo tal como é mostrado, sem as suas etiquetas, e sem cabeçalhos; um grupo mantém sob si o que contém). Os dois botões da barra de ferramentas também a mudam: lida em direto. Passar a alfabética com um cabeçalho selecionado limpa a seleção
ib_toolbarbooleantrueA barra de ferramentas: as duas vistas e a caixa de pesquisa. false oculta-a; is_sort e is_filter continuam a poder ser pilotados pelo código
ib_helpbooleantrueO painel de ajuda, em baixo: o rótulo e a descrição (is_description) da propriedade selecionada, o título de uma categoria selecionada
ii_label_widthinteger40Parte da largura dada aos rótulos, em percentagem, de 15 a 85. O utilizador arrasta a linha entre rótulos e valores: lida em direto
is_filterstring""A pesquisa: só ficam as propriedades cujo rótulo, chave ou valor mostrado contém este texto, sem distinguir maiúsculas; durante uma pesquisa, cada categoria e cada grupo com correspondência aparecem abertos, sem perder o seu estado. O rótulo lê-se tal como é mostrado, sem as suas etiquetas; nem o título de uma categoria nem o endereço completo são pesquisados. Durante uma pesquisa, recolher ou expandir pelo utilizador não faz nada; pelo seu código (ib_collapsed, ib_expanded, of_expand_all, of_collapse_all) fica registado, levanta o seu evento e vê-se assim que a pesquisa fica vazia; uma linha selecionada que a pesquisa esconde sai da seleção (ue_selection_changed com um endereço vazio). A caixa de pesquisa também a escreve (Esc limpa-a): lida em direto. "" mostra tudo
ib_veto_changesbooleanfalseOpt-in: perguntar antes de escrever um valor do utilizador (levanta ue_value_changing, que pode recusar: a célula volta a mostrar o valor anterior). Um valor escrito pelo seu código nunca pergunta
is_theme_stylestring""Estilo visual do componente (constantes THEME_STYLE_*); vazio = o da aplicação, seguido a cada mudança
is_theme_modestring""Variante clara ou escura (constantes THEME_MODE_*); vazio = a da aplicação, seguida a cada mudança
il_theme_accentlong-1Cor de destaque deste componente (-1 = destaque da aplicação, ou o do tema)
is_tooltipstring""Tooltip simples apresentado ao passar sobre o componente
is_super_tooltip_titlestring""Título do tooltip enriquecido (prevalece sobre is_tooltip)
is_super_tooltip_textstring""Texto do tooltip enriquecido (aceita marcação enriquecida)
is_super_tooltip_imagestring""Imagem do tooltip enriquecido

Propriedades de uma categoria — n_pbt_propertygrid_category #

PropriedadeTipoPredefiniçãoFunção
is_titlestring""Título do cabeçalho. Aceita o texto formatado com etiquetas. Vazio, o cabeçalho mostra a chave
ib_collapsedbooleanfalsetrue recolhe a categoria: o seu cabeçalho fica, as suas propriedades escondem-se (uma seleção que lá estava sobe para o cabeçalho). Segue-se ue_category_toggled, como num clique no cabeçalho. Durante uma pesquisa, cada categoria aparece aberta: um clique no cabeçalho não faz nada, e true definido pelo código fica registado (segue-se o evento, a leitura devolve-o) e vê-se assim que a pesquisa fica vazia. Lida em direto
ib_visiblebooleantruefalse retira a categoria, e tudo o que contém, da grelha; mantém a sua chave e os seus valores, que of_values continua a devolver
is_tooltipstring""Tooltip simples apresentado ao passar sobre o item
is_super_tooltip_titlestring""Título do tooltip enriquecido do item (prevalece sobre is_tooltip)
is_super_tooltip_textstring""Texto do tooltip enriquecido do item (aceita marcação enriquecida)
is_super_tooltip_imagestring""Imagem do tooltip enriquecido do item
il_accentlong-1Destaque do cabeçalho da categoria: a sua seleção usa-o (-1 = o do componente). Para a colorir por inteiro, il_back_color / il_text_color
il_back_colorlong-1Fundo do cabeçalho da categoria, em RGB(r,g,b) (-1 = o que o tema dá)
il_text_colorlong-1Cor do texto do cabeçalho da categoria (-1 = o que o tema dá)
il_back_color_hoverlong-1Fundo do cabeçalho da categoria sob o ponteiro (-1 = o que o tema dá)
il_text_color_hoverlong-1Cor do texto do cabeçalho da categoria sob o ponteiro (-1 = o que o tema dá)

Propriedades de uma propriedade — n_pbt_propertygrid_property #

PropriedadeTipoPredefiniçãoFunção
is_valuestringo de of_add_propertyO valor, em texto (ver Os tipos de valor); para uma lista, o valor da opção. Escrevê-lo não levanta nada, como SetItem; lê-lo dá o valor atual, seja quem for que o escreveu. Um valor que o seu tipo não pode conter (um TYPE_NUMBER que recebe um texto que não é um número) é recusado: o valor anterior fica, e of_get_last_error da grelha diz porquê. Num grupo (TYPE_GROUP), a leitura dá o seu resumo (ver is_summary), e a escrita é ignorada
is_labelstringo de of_add_propertyO nome mostrado na coluna da esquerda; aceita o texto formatado com etiquetas. Vazio, a linha mostra a chave, tal como está (nunca lida como etiquetas). A vista alfabética ordena-o, e a pesquisa lê-o, tal como é mostrado: sem as suas etiquetas
is_descriptionstring""O texto do painel de ajuda enquanto a propriedade está selecionada; aceita o texto formatado com etiquetas
ib_readonlybooleanfalseMostrada, não editável: o valor aparece a cinzento e nenhum editor se abre, nem com um clique, nem com o teclado, nem com um duplo clique. Um grupo só de leitura torna só de leitura tudo o que contém. O botão … (ib_ellipsis) continua ativo: leia ib_readonly em ue_ellipsis_clicked para abrir a sua caixa de diálogo só de leitura
ib_visiblebooleantruefalse retira a linha da grelha; a propriedade mantém o seu endereço e o seu valor (of_values continua a devolvê-lo). Ocultar um grupo oculta o que contém; ocultar a propriedade selecionada limpa a seleção
ib_ellipsisbooleanfalseUm botão … no fim da linha: um clique — ou Ctrl+Enter na linha selecionada — seleciona a linha e levanta ue_ellipsis_clicked, mesmo numa propriedade só de leitura, para uma caixa de diálogo sua (um ficheiro, um tipo de letra, uma lista tirada da base)
ib_expandedbooleanfalsePara uma propriedade expansível (TYPE_GROUP): true mostra o que contém, recuado sob ela; false esconde-o (uma seleção que lá estava sobe para o grupo). Segue-se ue_property_toggled, como num clique na sua seta. Durante uma pesquisa, um grupo com correspondência aparece aberto: a sua seta não faz nada, e um valor definido pelo código fica registado (segue-se o evento) e vê-se assim que a pesquisa fica vazia. Lida em direto; sem efeito nos outros tipos
is_summarystring""Para uma propriedade expansível (TYPE_GROUP): como se escreve o seu resumo, um modelo. {size} é o valor mostrado da sua subpropriedade size, {size:raw} o seu valor tal como é guardado (uma palavra-passe continua mascarada), {?bold}…{/bold} um pedaço mantido só quando bold está ativo (um booleano verdadeiro, um valor que não é vazio, nem false, nem 0), {!bold}…{/bold} só quando não está, {{ }} chavetas literais; uma chave desconhecida não dá nada. "{name}, {size} pt{?bold}, bold{/bold}" mostra Segoe UI, 10 pt, bold. Vazio (por omissão): os valores mostrados, ocultos saltados, unidos por ; . O resumo é texto simples; segue cada alteração do que o grupo contém; is_value do grupo devolve-o
is_maskstring""Para um TYPE_NUMBER: a sua máscara de introdução, uma máscara numérica na sintaxe do PowerBuilder (EditMask, formato DataWindow): # um algarismo opcional, 0 um algarismo obrigatório, , o agrupamento, . o separador decimal, % o número mostrado vezes 100, literais ($, um texto entre aspas, \x) e secções positivo;negativo ("$#,##0;($#,##0)"). A vírgula e o ponto designam os separadores da língua de apresentação. Durante a escrita, o agrupamento aparece à medida que chegam os algarismos, as casas decimais ficam limitadas à máscara, as letras são recusadas, o cursor mantém o seu lugar entre os algarismos e um número colado é lido na língua de apresentação; ao sair do campo a máscara completa (12 passa a 12,00). O valor mantém o número tal como o código o escreve ("1234.5"), sem agrupamento nem símbolo. Vazio (por omissão): o campo escreve-se segundo o seu is_format sem os seus literais ($#,##0.00 escreve-se #,##0.00, #,##0 "px" escreve-se #,##0; um % fica, é uma escala), senão o número tal como está; sem efeito nos outros tipos
is_formatstring""Para um TYPE_NUMBER: o seu formato de apresentação, como a célula mostra o número enquanto o seu campo não tem o teclado — a mesma sintaxe de is_mask, com os seus literais: #,##0 "px" mostra 575 px, $#,##0.00 um preço, 0.0% uma taxa (0,125 mostra 12,5%). O resumo de um grupo e a pesquisa também o leem. Quando o campo recebe o teclado, o seu texto passa a ser o de is_mask (575), o cursor mantendo o seu lugar entre os algarismos; ao sair volta o texto de apresentação. A troca nunca altera o valor e não levanta nada: ue_value_changed só relata o que o utilizador escreveu, o número nu. Vazio (por omissão): a célula mostra o seu is_mask; sem efeito nos outros tipos
is_defaultstring""O valor predefinido, em texto como is_value. Enquanto o valor for diferente, é escrito a negrito e o painel de ajuda mostra o predefinido; o utilizador repõe-no com Delete na linha selecionada ou com o botão Repor (↺) da barra de ferramentas, mostrado apenas quando pelo menos uma propriedade tem um predefinido — um gesto do utilizador: ue_value_changing se o veto estiver ativo, depois ue_value_changed. Um valor que o seu tipo não consegue conter é recusado. Escrever "" retira o predefinido: deixa de haver negrito e predefinido no painel de ajuda, lê-se "". Sem predefinido, Delete esvazia o valor (um booleano fica como está)
is_errorstring""Um erro da sua aplicação ("Este nome já existe"): o valor é emoldurado a vermelho, o painel de ajuda di-lo por extenso, tal como uma descrição, e um leitor de ecrã anuncia-o. Desaparece quando o utilizador altera a propriedade, ou quando escreve "". Posto em ue_value_changing antes de recusar, explica a recusa. Lido, o erro que a propriedade mostra: o seu, senão o da grelha quando um número digitado é recusado (não é um número, fora de is_min / is_max) — o texto digitado fica então no ecrã para ser corrigido, Esc desiste dele
is_minstring""Para um TYPE_NUMBER: o valor mais pequeno que o utilizador pode dar, como número escrito pelo código ("0", "12.5"); "" = sem limite. Um número digitado abaixo é recusado, fica no ecrã e o painel de ajuda diz porquê; Baixo para aí. O seu código pode sempre escrever qualquer valor. Um texto que não seja um número é recusado (of_get_last_error), tal como um limite que cruza o outro (is_min acima de is_max). Ignorada pelos outros tipos
is_maxstring""Para um TYPE_NUMBER: o maior valor que o utilizador pode dar; "" = sem limite. As mesmas regras de is_min; Cima para aí
id_stepdouble1Para um TYPE_NUMBER: o que Cima e Baixo somam ou subtraem enquanto o seu campo tem o teclado, dentro de is_min / is_max. Cada passo é um valor do utilizador (ue_value_changed, perguntado antes se o veto estiver ativo). 0 ou menos vale 1. Ignorado pelos outros tipos
of_is_dirty ( ) → boolean——TRUE quando o valor difere da sua referência (ver of_is_dirty da grelha)
of_type ( ) → string——O tipo dado a of_add_property (uma constante TYPE_*). Só de leitura: um tipo escolhe-se uma vez
is_tooltipstring""Tooltip simples apresentado ao passar sobre o item
is_super_tooltip_titlestring""Título do tooltip enriquecido do item (prevalece sobre is_tooltip)
is_super_tooltip_textstring""Texto do tooltip enriquecido do item (aceita marcação enriquecida)
is_super_tooltip_imagestring""Imagem do tooltip enriquecido do item
il_accentlong-1Destaque da linha da propriedade: a sua seleção e a moldura do seu editor usam-no (-1 = o do componente). Para a colorir por inteiro, il_back_color / il_text_color
il_back_colorlong-1Fundo da linha da propriedade, em RGB(r,g,b) (-1 = o que o tema dá)
il_text_colorlong-1Cor do texto da linha da propriedade (-1 = o que o tema dá)
il_back_color_hoverlong-1Fundo do rótulo da propriedade quando o ponteiro está sobre a sua linha (-1 = o que o tema dá)
il_text_color_hoverlong-1Cor do rótulo da propriedade quando o ponteiro está sobre a sua linha (-1 = o que o tema dá)

Métodos #

No componente #

MétodoFunção
of_add_category (string as_key, string as_title) → longAcrescenta uma categoria no fim: um cabeçalho que se recolhe, sob o qual se acrescentam depois as propriedades "chave/nome". Um título vazio mostra a chave. Devolve 0 uma vez acrescentada, -5 para uma chave vazia, que contenha / ou `, ou já ocupada por uma categoria ou uma propriedade de cima, -2` se o componente não estiver criado
of_add_property (string as_keys, string as_label, string as_type, string as_value) → longAcrescenta uma propriedade no seu endereço, no fim do que a contém: a sua categoria, o seu grupo ("appearance/font/size", "margin/left") ou as propriedades de cima. as_type é uma constante TYPE_*, as_value o seu valor em texto ("" para um TYPE_GROUP, que não tem). Devolve 0 uma vez acrescentada, -5 para um endereço já ocupado, um pai que não é nem uma categoria nem um grupo (ou ainda não acrescentado), um nível vazio ("layout/", "a//b"), uma chave que contenha `, um tipo desconhecido, um valor TYPE_NUMBER que não seja um número tal como o código o escreve (um ponto para as decimais, sinal e expoente opcionais, "" admitido), um booleano, uma data ou uma cor que não o sejam, um texto ou uma palavra-passe em várias linhas (of_get_last_error diz porquê) ou um valor dado a um TYPE_GROUP, -2` se o componente não estiver criado
of_add_option (string as_keys, string as_value, string as_text) → longAcrescenta uma opção, no fim, à lista de uma propriedade TYPE_ENUM: as_value é o que a propriedade contém (e o que ue_value_changed dá), as_text o que a lista mostra, como texto simples sem etiquetas ("" mostra o valor). Devolve 0 uma vez acrescentada, -5 para um endereço que não seja uma propriedade lista, um valor que esta propriedade já oferece, ou um valor que contenha ` ou / (of_keys_at designa uma opção pelo endereço da propriedade seguido do seu valor: um nível), -2` se o componente não estiver criado
of_remove_option (string as_keys, string as_value) → longRetira uma opção da lista de uma propriedade TYPE_ENUM, pelo seu valor. O valor que a propriedade contém fica como está, mesmo que fosse essa opção. Devolve 0 uma vez retirada, -5 para um endereço que não seja uma propriedade lista, ou um valor que a sua lista não oferece, -2 se o componente não estiver criado
of_clear_options (string as_keys) → longRetira todas as opções de uma propriedade TYPE_ENUM, para carregar outra lista sem perder a propriedade, o seu handle, a sua seleção nem os seus indicadores. O valor que contém fica como está: escreva o novo em is_value. Devolve 0 uma vez limpa, -5 para um endereço que não seja uma propriedade lista, -2 se o componente não estiver criado
of_category (string as_key) → n_pbt_propertygrid_categoryHandle de uma categoria, pela sua chave (criado no primeiro acesso): o seu título, o seu estado recolhido, a sua visibilidade e as suas cores definem-se através dele
of_property (string as_keys) → n_pbt_propertygrid_propertyHandle de uma propriedade, pelo seu endereço (criado no primeiro acesso): o seu valor, o seu rótulo, a sua descrição, os seus indicadores e as suas cores definem-se e leem-se através dele. Um endereço que esta grelha não acrescentou (um erro de escrita) dá um handle que não é guardado: escrever através dele não faz nada, e of_get_last_error diz porquê
of_remove_property (string as_keys) → longRetira uma propriedade, e o seu handle com ela; um grupo sai com tudo o que contém. Se estava selecionada, ue_selection_changed anuncia que já não há seleção. Devolve 0 uma vez retirada, -5 para um endereço que esta grelha nunca acrescentou, -2 se o componente não estiver criado
of_remove_category (string as_key) → longRetira uma categoria e todas as suas propriedades, com os seus handles. Se a seleção lá estava, ue_selection_changed anuncia que já não há nenhuma. Devolve 0 uma vez retirada, -5 para uma chave que esta grelha nunca acrescentou como categoria, -2 se o componente não estiver criado
of_clear ( ) → longLimpa a grelha: categorias, propriedades, opções e handles. A vista, a barra de ferramentas, o painel de ajuda e a pesquisa ficam como estão (é of_reset que repõe cada propriedade do componente). Se uma linha estava selecionada, segue-se ue_selection_changed com um endereço vazio. Devolve 0 uma vez limpa, -2 se o componente não estiver criado
of_select_property (string as_keys) → longSeleciona uma linha, como um clique: uma propriedade ("page/margin") ou o cabeçalho de uma categoria ("page"). O que contém a propriedade abre-se primeiro: a sua categoria recolhida, os seus grupos fechados (ue_category_toggled, ue_property_toggled) — só se a linha for então mostrada: uma chamada recusada não abre nada. Segue-se ue_selection_changed, como num clique. Devolve 0 uma vez selecionada (ou se já o estava), -5 para um endereço que esta grelha nunca acrescentou ou uma linha que não é mostrada (oculta, fora da pesquisa, para lá do limite da demonstração, um cabeçalho na vista alfabética), -2 se o componente não estiver criado
of_clear_selection ( ) → longNão deixa nenhuma linha selecionada; segue-se ue_selection_changed com um endereço vazio. Se já nada estava selecionado, nada é levantado. Devolve 0 uma vez aplicado, -2 se o componente não estiver criado
of_selected_key ( ) → stringEndereço da linha selecionada, lido em direto, seja quem for que a definiu: "page/margin", "page" para um cabeçalho, "" se nenhuma. Exatamente o que ue_selection_changed lhe entrega
of_expand_all ( ) → longExpande todas as categorias e abre todos os grupos; segue-se ue_category_toggled para cada categoria que estava recolhida, ue_property_toggled para cada grupo que estava fechado. Devolve 0 uma vez aplicado, -2 se o componente não estiver criado
of_collapse_all ( ) → longRecolhe todas as categorias e fecha todos os grupos; seguem-se ue_category_toggled e ue_property_toggled para cada um que muda. Devolve 0 uma vez aplicado, -2 se o componente não estiver criado
of_dirty_keys (ref string as_keys[]) → longPreenche as_keys[] com os endereços das propriedades que diferem da sua referência, pela ordem da vista por categoria, e devolve o seu número (0 = nada a guardar); o que o utilizador ainda está a escrever é validado primeiro
of_is_dirty ( ) → booleanTRUE quando pelo menos uma propriedade difere da sua referência: o valor com que foi acrescentada, ou o que of_load ou of_reset_update fizeram dele — tenha sido o utilizador ou o seu código a alterá-lo. O mesmo nome que no form. Não confundir com is_default, o valor mostrado a negrito: este diz o que há a guardar. O que o utilizador ainda está a escrever é validado primeiro, como para of_values
of_load (string as_json) → longCarrega valores de uma vez: um objeto JSON por endereço, a forma que of_values devolve — as propriedades de cima, um objeto por categoria e por grupo ({"name":"Orders","layout":{"width":800}}) — ou chaves "layout/width". Os valores são escritos em silêncio (nenhum ue_value_changed) e passam a ser a referência de of_is_dirty; os erros mostrados desaparecem. Uma propriedade que o objeto não nomeia mantém o seu valor, um número é lido algarismo a algarismo. Um valor que a grelha não consegue receber (nenhuma propriedade nesse endereço, um valor que o seu tipo não consegue conter) é saltado: o resto é escrito, e of_get_last_error nomeia os endereços saltados. O que o utilizador estava a escrever é abandonado. Devolve 0 uma vez aplicado (mesmo com valores saltados), -5 para um texto que não seja um objeto JSON, -2 se o componente não estiver criado
of_reset_update ( ) → longOs valores presentes passam a ser a referência: of_is_dirty volta a responder FALSE. Chame-o depois de guardar as suas definições, como ResetUpdate de um DataWindow. Devolve 0 uma vez aplicado, -2 se o componente não estiver criado
of_revert ( ) → longRepõe cada propriedade no seu valor de referência, em silêncio (nenhum evento, como um valor escrito pelo código), e retira os erros mostrados; o que o utilizador estava a escrever é abandonado (depois nada é levantado): o botão Cancelar da sua janela de definições. Devolve 0 uma vez aplicado, -2 se o componente não estiver criado
of_clear_errors ( ) → longRetira todos os erros da sua aplicação (is_error de cada propriedade). Um número digitado que a grelha recusou fica: o utilizador tem de o corrigir. Devolve 0 uma vez aplicado, -2 se o componente não estiver criado
of_focus_property (string as_keys) → longPõe o teclado numa propriedade, como um clique no seu valor: o que a contém abre-se primeiro (ue_category_toggled, ue_property_toggled), fica selecionada (ue_selection_changed) e o seu editor recebe o teclado; um grupo ou uma propriedade só de leitura: a grelha. Devolve 0, -5 para um endereço que esta grelha nunca acrescentou ou uma linha que não pode ser mostrada (oculta, fora da pesquisa, para lá do limite da demonstração), -2 se o componente não estiver criado
of_invalid_keys (ref string as_keys[]) → longPreenche as_keys[] com os endereços das propriedades com erro, pela ordem da vista por categoria, e devolve o seu número (0 = a grelha é válida); o que o utilizador ainda está a escrever é validado primeiro
of_is_valid ( ) → booleanTRUE quando nenhuma propriedade mostrada tem um erro: nem o seu (is_error), nem o da grelha (um número digitado recusado: não é um número, fora de is_min / is_max). O que o utilizador ainda está a escrever é validado primeiro: um texto recusado conta. O mesmo nome que no form
of_validate ( ) → longPõe o teclado na primeira propriedade com erro — a sua categoria e os seus grupos abrem-se, fica selecionada e o seu editor recebe o teclado: o que o seu botão OK chama antes de guardar. O que o utilizador ainda está a escrever é validado primeiro. Devolve o número de propriedades com erro (0 = a grelha é válida, nada se move), -2 se o componente não estiver criado
of_values ( ) → stringTodos os valores de uma vez, lidos em direto — o que o utilizador ainda está a escrever é validado primeiro, como por AcceptText (ue_value_changing se o veto estiver ativo, depois ue_value_changed) —, num objeto JSON: as propriedades de cima, depois cada categoria como um objeto próprio, cada grupo como um objeto dentro do que o contém — ocultas incluídas. Tipados: um número é um número, escrito algarismo a algarismo (um decimal de 21 algarismos continua exato), um booleano um booleano, uma cor o seu long RGB, o resto texto. Lê-se com n_pbt_json, pelo mesmo endereço: lnv_json.of_get_number("page/margin"), lnv_json.of_get_number("appearance/font/size")
of_reset ( ) → longLimpa a grelha (of_clear) e depois repõe cada propriedade do componente no seu valor por omissão: vista por categoria, barra de ferramentas e painel de ajuda visíveis, rótulos a 40 %, pesquisa vazia, pergunta desativada. Devolve 0 uma vez aplicado, -2 se o componente não estiver criado

Numa categoria e numa propriedade #

Uma categoria contém propriedades; um grupo (TYPE_GROUP) contém as suas subpropriedades; uma propriedade lista (TYPE_ENUM) contém as suas opções, designadas pelo seu valor. Os três métodos percorrem-nas.

MétodoFunção
of_count ( ) → longNúmero de propriedades da categoria, ocultas incluídas; número de subpropriedades de um grupo; número de opções de uma propriedade lista (0 para os outros tipos)
of_keys_at (long al_index) → stringEndereço da propriedade de posição al_index (a partir de 1) — "page/margin", "appearance/font/size" num grupo, reutilizável tal como está em of_property; numa propriedade lista, o endereço seguido do valor da opção. "" fora dos limites
of_has (string as_key) → booleanA categoria ou o grupo contém esta propriedade? A propriedade lista oferece este valor?

Eventos #

EventoAcionado quando
ue_value_changed (string as_keys, string as_value)O utilizador alterou um valor (uma entrada validada com Enter ou ao sair da célula, uma caixa assinalada com um clique, Espaço ou Enter / F2, uma escolha numa lista, uma cor, uma data, um duplo clique num rótulo). as_keys é o endereço da propriedade, as_value o seu novo valor em texto; já está escrito. Um valor escrito pelo seu código (is_value) não levanta nada, como SetItem: o seu código sabe o que escreveu. Delete ou o botão Repor (regresso ao predefinido) e Cima / Baixo num número são gestos do utilizador: também o levantam
ue_value_changing (string as_keys, string as_value) → booleanCancelável, colocado antes de um valor do utilizador ser escrito, e só quando ib_veto_changes = true (desativado por omissão). Devolver FALSE recusa: a célula volta a mostrar o valor anterior, que of_property(as_keys).is_value ainda devolve durante o evento. Devolva TRUE para aceitar. Ponha of_property(as_keys).is_error antes de recusar: o utilizador lê porquê
ue_selection_changed (string as_from_keys, string as_keys)A seleção mudou: um clique, o teclado, ou o seu código (of_select_property, of_clear_selection — uma ordem também o levanta, como SelectItem), ou a linha selecionada saiu: recolhida na sua categoria ou no seu grupo (as_keys é então esse cabeçalho ou esse grupo), retirada, ou já não desenhada — ocultada, escondida pela pesquisa (mesmo por um recolhimento feito durante ela), para lá do limite da demonstração (as_keys vale então ""). Uma linha é uma propriedade ("page/margin") ou o cabeçalho de uma categoria ("page"); as_from_keys é a que foi deixada
ue_category_toggled (string as_key, boolean ab_collapsed)Uma categoria recolheu-se (ab_collapsed = TRUE) ou expandiu-se: um clique no seu cabeçalho, o teclado, o seu ib_collapsed definido pelo seu código, of_expand_all, of_collapse_all, ou of_select_property sobre uma propriedade que contém
ue_property_toggled (string as_keys, boolean ab_expanded)Uma propriedade expansível (TYPE_GROUP) abriu-se (ab_expanded = TRUE) ou fechou-se: um clique na sua seta, um duplo clique no seu rótulo, o teclado, o seu ib_expanded definido pelo seu código, of_expand_all, of_collapse_all, ou of_select_property sobre o que contém. as_keys é o endereço do grupo
ue_ellipsis_clicked (string as_keys)O botão … de uma propriedade (ib_ellipsis) foi clicado, ou Ctrl+Enter foi premido na sua linha: abra a sua caixa de diálogo e depois escreva o resultado em of_property(as_keys).is_value. O botão continua ativo numa propriedade só de leitura: of_property(as_keys).ib_readonly diz se deve abrir a sua caixa de diálogo só de leitura
ue_ready ( )O componente terminou o carregamento; tudo o que foi enviado antes foi reproduzido
ue_runtime_missing ( )O runtime WebView2 está ausente: o componente permanece vazio
ue_bg_color (long al_color)O componente calculou a cor de fundo do respetivo tema; o userobject já a adotou (backcolor)

Teclado e rato #

GestoEfeito
Setas cima / baixo, Home / End, Page Up / Page DownMovem a seleção de linha em linha; Page Up / Page Down avançam a altura da lista
Setas esquerda / direitaNum cabeçalho, recolhem ou expandem a categoria; num grupo, Direita abre-o e Esquerda fecha-o; Direita num cabeçalho ou num grupo já abertos desce para a sua primeira linha; numa propriedade, Esquerda sobe para o que a contém, o seu grupo ou o seu cabeçalho (invertidas da direita para a esquerda). Durante uma pesquisa, recolher ou expandir não faz nada, nem pelo teclado nem pelo rato
Enter, F2Entram no editor da propriedade (abrem a lista, o seletor de cor ou o calendário); um booleano alterna; num cabeçalho ou num grupo, recolhem ou expandem. Sem nada a fazer (nenhuma linha, uma propriedade só de leitura), a tecla é deixada à janela: o seu botão por omissão
EspaçoAssinala ou desassinala um booleano; num cabeçalho ou num grupo, recolhe ou expande
Enter / Esc num editorValida a entrada / repõe o valor anterior; o teclado volta à lista. Esc num campo não alterado é deixado à janela: o seu botão Cancelar
Ctrl+EnterO botão … da linha selecionada (ue_ellipsis_clicked)
TabA lista de propriedades é uma única paragem de tabulação, qualquer que seja o seu tamanho: dos editores, só os da linha selecionada aceitam Tab; a lista que tem o teclado sem linha selecionada mostra um contorno
Duplo clique num rótuloUm booleano alterna, uma lista passa à opção seguinte, um grupo abre-se ou fecha-se
DeleteNa linha selecionada: repõe o valor predefinido (is_default) ou, sem predefinido, esvazia o valor — um texto, um número, uma data, uma cor, uma lista; um booleano sem predefinido fica. O botão Repor (↺) da barra de ferramentas também repõe o predefinido. Um gesto do utilizador: ue_value_changed
Retrocesso, uma tecla de carácterNa linha selecionada de um texto, um número ou uma palavra-passe: começam a entrada — Retrocesso abre o editor, o texto mantido e o cursor no fim (já não esvazia o valor); uma tecla de carácter abre o editor com esse carácter, como na janela de propriedades do Visual Studio. Numa lista, uma cor, uma data ou uma caixa: nada
F4, Alt+BaixoAbrem a lista, o seletor de cor ou o calendário da linha selecionada, a partir da lista ou do seu botão, como uma lista pendente do Windows
Cima / Baixo num númeroSomam / subtraem id_step, dentro de is_min / is_max; cada passo levanta ue_value_changed
Separador: Esquerda / Direita, Início / FimA linha entre rótulos e valores aceita o teclado (Tab): Esquerda / Direita movem-na 5 % (invertidas da direita para a esquerda), Início / Fim levam-na aos extremos (ii_label_width)
Arrastar a linha entre rótulos e valoresMuda ii_label_width
Caixa de pesquisa: Esc / Seta para baixo ou EnterLimpa a pesquisa / passa para a lista, na primeira linha se nenhuma estiver selecionada

Exemplos #

As definições de uma janela #

// The whole grid in one paint
uo_grid.of_set_redraw(/*on*/ false)

// At the top, without a category : the name of the window
uo_grid.of_add_property(/*keys*/ "name", /*label*/ "Name", /*type*/ u_pbt_propertygrid.TYPE_STRING, /*value*/ "Customers")

// A value given by the application : shown, not editable
uo_grid.of_add_category(/*key*/ "identity", /*title*/ "Identity")
uo_grid.of_add_property(/*keys*/ "identity/id", /*label*/ "Id", /*type*/ u_pbt_propertygrid.TYPE_STRING, /*value*/ "W-0042")
uo_grid.of_property(/*keys*/ "identity/id").ib_readonly = true
uo_grid.of_add_property(/*keys*/ "identity/created", /*label*/ "Created on", /*type*/ u_pbt_propertygrid.TYPE_DATE, /*value*/ String(Today(), "yyyy-mm-dd"))

// A number, a check box and a list of choices
uo_grid.of_add_category(/*key*/ "layout", /*title*/ "Layout")
uo_grid.of_add_property(/*keys*/ "layout/width", /*label*/ "Width", /*type*/ u_pbt_propertygrid.TYPE_NUMBER, /*value*/ "1200")
uo_grid.of_add_property(/*keys*/ "layout/resizable", /*label*/ "Resizable", /*type*/ u_pbt_propertygrid.TYPE_BOOLEAN, /*value*/ "true")
uo_grid.of_add_property(/*keys*/ "layout/state", /*label*/ "Window state", /*type*/ u_pbt_propertygrid.TYPE_ENUM, /*value*/ "normal")
uo_grid.of_add_option(/*keys*/ "layout/state", /*value*/ "normal", /*text*/ "Normal")
uo_grid.of_add_option(/*keys*/ "layout/state", /*value*/ "maximized", /*text*/ "Maximized")

// A colour, as its RGB long written out
uo_grid.of_add_category(/*key*/ "appearance", /*title*/ "Appearance")
uo_grid.of_add_property(/*keys*/ "appearance/back_color", /*label*/ "Back colour", /*type*/ u_pbt_propertygrid.TYPE_COLOR, /*value*/ String(RGB(/*red*/ 240, /*green*/ 244, /*blue*/ 250)))

// One single paint, then the first value to edit
uo_grid.of_set_redraw(/*on*/ true)
uo_grid.of_select_property(/*keys*/ "layout/width")

Um inspetor que aplica cada alteração #

// event ue_value_changed of uo_grid : (string as_keys, string as_value)
// The address says which setting of the window the user changed
choose case as_keys
    case "name"
        w_customers.title = as_value
    case "layout/width"
        w_customers.width = Long(as_value)
    case "layout/resizable"
        w_customers.resizable = (as_value = "true")
    case "appearance/back_color"
        w_customers.backcolor = Long(as_value)
end choose

O botão …: uma caixa de diálogo sua #

// The icon : typed by hand, or chosen through the "..." button
uo_grid.of_add_property(/*keys*/ "appearance/icon", /*label*/ "Icon", /*type*/ u_pbt_propertygrid.TYPE_STRING, /*value*/ "img\customers.png")
uo_grid.of_property(/*keys*/ "appearance/icon").ib_ellipsis = true
// event ue_ellipsis_clicked of uo_grid : (string as_keys)
// Local variables
string ls_path, ls_file
constant unsignedlong OFN_EXPLORER = 2
constant unsignedlong OFN_NOCHANGEDIR = 64

// The application opens its own dialog - in the Explorer style, without moving the current folder of the application - then writes the result (this raises nothing)
if GetFileOpenName("Icon", ls_path, ls_file, "png", "Pictures (*.png),*.png", /*initdir*/ "", OFN_EXPLORER + OFN_NOCHANGEDIR) = 1 then
    uo_grid.of_property(/*keys*/ as_keys).is_value = ls_path
end if

Validar antes de escrever #

// The question is OFF by default : turn it on to be able to refuse a value
uo_grid.ib_veto_changes = true
// event ue_value_changing of uo_grid : (string as_keys, string as_value)
// FALSE refuses : the cell shows the old value again. is_error, set before, tells
// the user why : the help pane shows it until the value is edited again
choose case as_keys
    case "layout/width"
        if Long(as_value) < 200 or Long(as_value) > 4000 then
            uo_grid.of_property(/*keys*/ as_keys).is_error = "Between 200 and 4000 pixels."
            return false
        end if
    case "name"
        if Trim(as_value) = "" then
            uo_grid.of_property(/*keys*/ as_keys).is_error = "A window needs a name."
            return false
        end if
end choose

// Any other value is accepted
return true

Valores predefinidos, alterações e Cancelar #

Duas noções distintas, como na janela de propriedades do Visual Studio e num DataWindow: o valor predefinido (is_default) diz o que se escreve a negrito e o que Delete repõe; a referência (of_load, of_reset_update) diz o que há a guardar (of_is_dirty, of_dirty_keys) e o que Cancelar repõe (of_revert).

// The defaults of the window : a value that differs is written in bold
uo_grid.of_property(/*keys*/ "layout/width").is_default = "800"
uo_grid.of_property(/*keys*/ "layout/state").is_default = "normal"

// The width the user may type, and what Up / Down add or take
uo_grid.of_property(/*keys*/ "layout/width").is_min = "200"
uo_grid.of_property(/*keys*/ "layout/width").is_max = "4000"
uo_grid.of_property(/*keys*/ "layout/width").id_step = 50

// The saved settings, read back : they become the reference
uo_grid.of_load(/*json*/ is_saved_settings)
// OK : every value right first - otherwise the keyboard goes to the first error
if uo_grid.of_validate() > 0 then return

// Save only what changed (what the user is still typing counts too), then the screen becomes the reference
if uo_grid.of_is_dirty() then
    is_saved_settings = uo_grid.of_values()
    uo_grid.of_reset_update()
end if
// Cancel : every value back to the settings loaded
uo_grid.of_revert()

Uma propriedade expansível #

Um tipo de letra cabe numa linha fechada, que resume os seus valores, e abre-se sobre as suas três propriedades. Sem modelo o resumo é Segoe UI; 9; False; is_summary escreve-o à sua maneira: Segoe UI, 9 pt, e depois , bold enquanto Bold estiver marcado.

// A group in the category appearance : the font, closed when it is added
uo_grid.of_add_category(/*key*/ "appearance", /*title*/ "Appearance")
uo_grid.of_add_property(/*keys*/ "appearance/font", /*label*/ "Font", /*type*/ u_pbt_propertygrid.TYPE_GROUP, /*value*/ "")

// What it holds is added at its address
uo_grid.of_add_property(/*keys*/ "appearance/font/name", /*label*/ "Name", /*type*/ u_pbt_propertygrid.TYPE_STRING, /*value*/ "Segoe UI")
uo_grid.of_add_property(/*keys*/ "appearance/font/size", /*label*/ "Size", /*type*/ u_pbt_propertygrid.TYPE_NUMBER, /*value*/ "9")
uo_grid.of_add_property(/*keys*/ "appearance/font/bold", /*label*/ "Bold", /*type*/ u_pbt_propertygrid.TYPE_BOOLEAN, /*value*/ "false")

// Its summary, written your way : "Segoe UI, 9 pt", then ", bold" while Bold is checked
uo_grid.of_property(/*keys*/ "appearance/font").is_summary = "{name}, {size} pt{?bold}, bold{/bold}"

// Open it : its three values show under it
uo_grid.of_property(/*keys*/ "appearance/font").ib_expanded = true
// Local variables
n_pbt_json lnv_json
double ld_size

// The group is an object in the values : the same address reads its size
lnv_json.of_load(/*json*/ uo_grid.of_values())
ld_size = lnv_json.of_get_number(/*path*/ "appearance/font/size")
// event ue_property_toggled of uo_grid : (string as_keys, boolean ab_expanded)
// The group that opened or closed, by its address
if ab_expanded then
    lb_log.AddItem(as_keys + " opened")
else
    lb_log.AddItem(as_keys + " closed")
end if

Ler todos os valores de uma vez #

// Local variables
n_pbt_json lnv_json
string ls_state

// Every value, typed, read along the same addresses as the grid
lnv_json.of_load(/*json*/ uo_grid.of_values())
w_customers.title = lnv_json.of_get_string(/*path*/ "name")
w_customers.width = lnv_json.of_get_number(/*path*/ "layout/width")
w_customers.resizable = lnv_json.of_get_boolean(/*path*/ "layout/resizable")

// One value alone : always text
ls_state = uo_grid.of_property(/*keys*/ "layout/state").is_value

Vistas, pesquisa e largura dos rótulos #

// One flat list sorted by label, instead of the categories
uo_grid.is_sort = u_pbt_propertygrid.SORT_ALPHABETICAL

// Keep only what speaks of a colour
uo_grid.is_filter = "colour"

// The labels take half of the width, and the help pane goes away
uo_grid.ii_label_width = 50
uo_grid.ib_help = false

Percorrer uma categoria #

// Local variables
n_pbt_propertygrid_category lnv_layout
string ls_keys
long ll_i

// Each property of the category, by its full address
lnv_layout = uo_grid.of_category(/*key*/ "layout")
for ll_i = 1 to lnv_layout.of_count()
    ls_keys = lnv_layout.of_keys_at(/*index*/ ll_i)
    lb_values.AddItem(ls_keys + " = " + uo_grid.of_property(/*keys*/ ls_keys).is_value)
next

Recarregar uma lista de opções #

// The states offered depend on the kind of window : the old choices go,
// the property keeps its handle, its flags and its place
uo_grid.of_clear_options(/*keys*/ "layout/state")

// The new choices, then the value to show among them
uo_grid.of_add_option(/*keys*/ "layout/state", /*value*/ "docked", /*text*/ "Docked")
uo_grid.of_add_option(/*keys*/ "layout/state", /*value*/ "floating", /*text*/ "Floating")
uo_grid.of_property(/*keys*/ "layout/state").is_value = "docked"

Boas práticas #

Herdado da base comum #

Estes membros existem em todos os componentes visuais — não são próprios deste. São detalhados uma só vez, nos capítulos transversais; esta tabela apenas diz onde os ler.

MembrosFunçãoDetalhado em
of_count · of_keys_at · of_hasPercorrer o que o componente contém3.2 Os items
of_resetRepor o componente a zero3.6 Repor um componente a zero: of_reset()
of_register_shortcut · of_clear_shortcutsAtalhos de teclado do componente3.5 Os atalhos de teclado
of_is_created · of_is_ready · of_get_last_errorSe nasceu, se está pronto, o que falhou3.7 Diagnóstico
of_save_as_png · of_save_as_jpgExportar a renderização como imagem3.8 Exportar a representação como imagem
of_set_redrawAgrupar as alterações num único repinte3.10 Boas práticas
of_preload_iconsÍcones mostrados sem atrasoApresentação instantânea: of_icon
of_set_translationTraduzir uma legenda do componente5.2 Adaptar uma etiqueta: of_set_translation
of_focus_webviewDar o foco ao componente6.4 Teclado e focus
of_print · of_print_to_pdfImprimir, ou escrever um PDF6.9 Imprimir
of_set_property · of_get_property · of_component_nameControlar uma propriedade pelo nome3.1 O motor de propriedades
is_accessible_name · is_accessible_descriptionO nome e a descrição que um leitor de ecrã diz3.4 Propriedades e eventos opcionais

Duas ajudas não são herdadas: of_icon e of_escape_markup vivem em n_pbt_utils. Declare um — n_pbt_utils lnv_utils, nada a criar — e chame-as nele.

← Referência dos componentes · Índice do guia