El componente TTreeView Delphi (ubicado en la pestaña de la paleta de componentes "Win32") representa una ventana que muestra un lista jerárquica de elementos, como los encabezados en un documento, las entradas en un índice o los archivos y directorios en un disco
Nodo de árbol con casilla de verificación o botón de radio
TTreeview de Delphi no admite casillas de verificación de forma nativa, pero el control WC_TREEVIEW subyacente sí. Puede agregar casillas de verificación a vista de árbol anulando el procedimiento CreateParams de TTreeView, especificando el estilo TVS_CHECKBOXES para el control. El resultado es que todos nodos en la vista de árbol tendrá casillas de verificación adjuntas. Además, la propiedad StateImages ya no se puede usar porque WC_TREEVIEW usa esta lista de imágenes internamente para implementar casillas de verificación. Si desea alternar las casillas de verificación, deberá hacerlo utilizando Enviar mensaje o la TreeView_SetItem / TreeView_GetItem macros desde CommCtrl.pas. WC_TREEVIEW solo admite casillas de verificación, no botones de radio.
El enfoque que debe descubrir en este artículo es mucho más flexible: puede tener casillas de verificación y botones de radio mezclados con otros nodos de la forma que desee sin cambiar la vista TTreeview o crear un nuevo clase para que esto funcione. Además, usted decide qué imágenes usar para las casillas de verificación / botones de radio simplemente agregando las imágenes adecuadas a la lista de imágenes de StateImages.
Agregar una casilla de verificación o botón de radio
Al contrario de lo que pueda creer, esto es bastante simple de lograr en Delphi. Estos son los pasos para que funcione:
- Configure una lista de imágenes (componente TImageList en la pestaña de la paleta de componentes "Win32") para la vista TTreeview. Propiedad StateImages que contiene las imágenes para los estados marcados y no marcados para casillas de verificación y / o botones de opción.
- Llame al procedimiento ToggleTreeViewCheckBoxes (ver más abajo) en los eventos OnClick y OnKeyDown de la vista de árbol. El procedimiento ToggleTreeViewCheckBoxes altera el índice de estado del nodo seleccionado para reflejar el estado actual marcado / no marcado.
Para que su vista de árbol sea aún más profesional, debe verificar dónde se hace clic en un nodo antes de alternar las imágenes de estado: solo alternando el nodo cuando se hace clic en la imagen real, los usuarios aún pueden seleccionar el nodo sin cambiar su estado.
Además, si no desea que sus usuarios expandan / contraigan la vista de árbol, llame al procedimiento FullExpand en el evento OnShow de formularios y establezca AllowCollapse en falso en el evento OnCollapsing de la vista de árbol.
Aquí está la implementación del procedimiento ToggleTreeViewCheckBoxes:
procedimiento ToggleTreeViewCheckBoxes (
Nodo: TTreeNode;
no verificado,
cComprobado
cRadioUnchecked,
cRadioChecked: entero);
var
tmp: TTreeNode;
comenzar Asignado (Nodo) entoncesbeginif Nodo. StateIndex = cUnChecked luego
Nodo. StateIndex: = cChecked
másSi Nodo. StateIndex = cChecked luego
Nodo. StateIndex: = cUnChecked
si no si Nodo. StateIndex = cRadioUnChecked entonces comenzar
tmp: = Nodo Padre;
si no Asignado (tmp) luego
tmp: = TTreeView (Nodo. TreeView) .Items.getFirstNode
más
tmp: = tmp.getFirstChild;
mientras Asignado (tmp) dobeginif (tmp. StateIndex en
[cRadioUnChecked, cRadioChecked]) luego
tmp. StateIndex: = cRadioUnChecked;
tmp: = tmp.getNextSibling;
final;
Nodo. StateIndex: = cRadioChecked;
final; // if StateIndex = cRadioUnCheckedfinal; // if Assigned (Node)
final; (* ToggleTreeViewCheckBoxes *)
Como puede ver en el código anterior, el procedimiento comienza al encontrar los nodos de las casillas de verificación y simplemente activarlos o desactivarlos. A continuación, si el nodo es un botón de opción sin marcar, el procedimiento se mueve al primer nodo en el nivel actual, establece todos los nodos en ese nivel a cRadioUnchecked (si son nodos cRadioUnChecked o cRadioChecked) y finalmente alterna Node a cRadioChecked.
Observe cómo se ignoran los botones de radio ya marcados. Obviamente, esto se debe a que un botón de radio ya marcado se deshabilitaría, dejando los nodos en un estado indefinido. Apenas lo que querrías la mayor parte del tiempo.
Aquí se explica cómo hacer que el código sea aún más profesional: en el evento OnClick de Treeview, escriba el siguiente código para alternar solo el casillas de verificación si se hizo clic en la imagen de estado (las constantes cFlatUnCheck, cFlatChecked, etc. se definen en otra parte como índices en StateImages lista de imágenes):
procedimiento TForm1.TreeView1Click (Remitente: TObject);
var
P: TPoint;
empezar
GetCursorPos (P);
P: = TreeView1.ScreenToClient (P);
Si (htOnStateIcon en
TreeView1.GetHitTestInfoAt (P.X, P.Y)) luego
ToggleTreeViewCheckBoxes (
TreeView1.Seleccionado,
cFlatUnCheck,
cFlatChecked,
cFlatRadioUnCheck,
cFlatRadioChecked);
final; (* TreeView1Click *)
El código obtiene la posición actual del mouse, se convierte en coordenadas de vista de árbol y comprueba si se hizo clic en StateIcon llamando a la función GetHitTestInfoAt. Si fue así, se llama al procedimiento de alternancia.
Principalmente, esperaría que la barra espaciadora alterne casillas de verificación o botones de radio, así que aquí le mostramos cómo escribir el evento TreeView OnKeyDown usando ese estándar:
procedimiento TForm1.TreeView1KeyDown (
Remitente: TObject;
Clave var: Word;
Shift: TShiftState);
comenzar (Clave = VK_SPACE) y
Asignado (TreeView1.Selected) luego
ToggleTreeViewCheckBoxes (
TreeView1.Seleccionado,
cFlatUnCheck,
cFlatChecked,
cFlatRadioUnCheck,
cFlatRadioChecked);
final; (* TreeView1KeyDown *)
Finalmente, así es como se verían los eventos OnShow del formulario y OnChanging del Treeview si quisiera evitar el colapso de los nodos del treeview:
procedimiento TForm1.FormCreate (Remitente: TObject);
empezar
TreeView1.FullExpand;
final; (* FormCreate *)
procedimiento TForm1.TreeView1Collapsing (
Remitente: TObject;
Nodo: TTreeNode;
var AllowCollapse: Boolean);
empezar
AllowCollapse: = falso;
final; (* TreeView1Collapsing *)
Finalmente, para verificar si un nodo está marcado, simplemente haga la siguiente comparación (en el controlador de eventos OnClick de un botón, por ejemplo):
procedimiento TForm1.Button1Click (Remitente: TObject);
var
BoolResult: boolean;
tn: TTreeNode;
comenzar Asignado (TreeView1.Selected) entonces comenzar
tn: = TreeView1.Selected;
BoolResult: = tn. StateIndex en
[cFlatChecked, cFlatRadioChecked];
Memo1.Text: = tn. Texto +
#13#10 +
'Seleccionado:' +
BoolToStr (BoolResult, True);
final;
final; (* Botón1Haga clic *)
Aunque este tipo de codificación no puede considerarse como una misión crítica, puede dar a sus aplicaciones una apariencia más profesional y más fluida. Además, al usar las casillas de verificación y los botones de opción con criterio, pueden hacer que su aplicación sea más fácil de usar. ¡Seguro que se verán bien!
Esta imagen a continuación fue tomada de una aplicación de prueba usando el código descrito en este artículo. Como puede ver, puede mezclar libremente nodos con casillas de verificación o botones de opción con los que no tienen ninguno, aunque no debe mezclar nodos "vacíos" con "caja"nodos (eche un vistazo a los botones de radio en la imagen) ya que esto hace que sea muy difícil ver qué nodos están relacionados.