Cómo hacer que DBGrid dibuje Sí/No en lugar de Verdadero/Falso
Frecuentes
Visto 6,219 veces
3
Estoy tratando de reemplazar Verdadero/Falso con Sí/No en un DBGrid. El siguiente código casi funciona:
procedure TDatamodule1.DBGridDrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
sText : String;
begin
if (UpperCase(Column.Field.FieldName) = UpperCase('Approved')) or
(UpperCase(Column.Field.FieldName) = UpperCase('Obsolete')) then
begin
if Column.Field.Value = True then
sText := 'Yes'
Else
If Column.Field.Value = False Then
sText := 'No'
Else
sText := '';
(Sender as TDBGrid).Canvas.FillRect(Rect);
(Sender as TDBGrid).Canvas.TextRect(Rect, Rect.Left+3, Rect.Top+2, sText);
end;
end;
Esto pareció funcionar hasta que comencé a usar las teclas de cursor del teclado para moverme por la cuadrícula. La celda que tiene el foco siempre tiene tanto Verdadero como Sí o Falso y No dibujados uno encima del otro. ¿Cómo evito que se dibuje la etiqueta predeterminada Verdadero/Falso en la celda que tiene el foco? Todas las demás celdas de la cuadrícula son perfectas.
Editar: no mencioné que la cuadrícula está configurada en Solo lectura y me di cuenta de que el problema está tanto seleccionado como enfocado. Gracias por adelantado.
4 Respuestas
11
Una solución simple sería configurar su campo booleano DisplayValues
:
MyField.DisplayValues := 'Yes;No';
Respondido el 10 de Septiembre de 13 a las 10:09
4
Una forma de lograr esto es establecer un controlador de eventos OnGetText para estos campos. Si tiene campos estáticos, puede configurarlos durante el tiempo de diseño. Con campos dinámicos puedes hacerlo en el evento FormCreate.
procedure TMyForm.MyFieldGetText(Sender: TField; var Text: string; DisplayText: Boolean);
begin
if Sender.AsBoolean then
Text := 'Yes'
else
Text := 'No';
end;
Respondido el 10 de Septiembre de 13 a las 07:09
Uwe, todavía no estoy lo suficientemente familiarizado con Delphi para entender cómo aplicar esto a los campos "dinámicos". En este caso, mi conjunto de datos de cliente no tiene estructura hasta que se ejecuta la consulta de la base de datos (tengo varias consultas). Un procedimiento MyFieldGetText me confunde cuando "MyField" no se conoce hasta después de la consulta. Debo decir que estoy realmente impresionado con la profundidad del conocimiento aquí en SO, ¡es bastante humillante para el principiante! - Mike
0
Yo diría que estás trabajando en el nivel equivocado de abstracción. Use dos columnas calculadas (AFlag y OFlag en el ejemplo a continuación) y defina un evento OnCalcFields para su conjunto de datos de cliente. El siguiente código se adjunta a un conjunto de datos llamado 'qCpap'.
procedure TView.qCpapCalcFields(DataSet: TDataSet);
begin
if qCpapApproved.AsBoolean
then qCpapAFlag.AsString:= 'Yes'
else qCpapAFlag.AsString:= 'No';
if qCpapObsolete.AsBoolean
then qCpapOFlag.AsString:= 'Yes'
else qCpapOFlag.AsString:= 'No';
end;
Por cierto, no tiene sentido usar la función 'mayúsculas' en una constante de cadena: también puede escribir la cadena en mayúsculas usted mismo.
Respondido el 10 de Septiembre de 13 a las 04:09
No'am, gracias por la respuesta. Preferiría volver a dibujar en lugar de tener campos de cálculo, ya que puedo usar este concepto para otros propósitos. Si no se puede volver a dibujar, probaré tu sugerencia. Anotado en el comentario en mayúsculas, está ahí por mi propia pereza. Si alguna vez lo edito más tarde, no tengo que preocuparme por usar el caso incorrecto. - Mike
@Mike: intente mirar el evento OnGetData de los campos. Nunca he usado esto, pero creo que puedes sobrecargarlo y sustituir tus valores aquí. Sería mucho más simple que su método. - No soy Newman
0
Resolví mi problema con mucha prueba y error. Primero, en los componentes de DBGrid configuré dgEditing en falso porque no era necesario (mi cuadrícula es de solo lectura). Esto evita que el usuario coloque la celda en el modo enfocado. En segundo lugar, establecí DefaultDrawing en False. Actualicé mi procedimiento DBGridDrawColumnCell de la siguiente manera:
procedure TDatamodule1.DBGridDrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
sText : String;
begin
if gdselected in state then { set proper colors if cell is selected }
Begin
(Sender as TDBGrid).Canvas.Font.Color :=
TStyleManager.ActiveStyle.GetSystemColor(clwindowtext);
(Sender as TDBGrid).Canvas.Brush.Color :=
TStyleManager.ActiveStyle.GetSystemColor(clhighlight);
End;
if (UpperCase(Column.Field.FieldName) = 'APPROVED') or
(UpperCase(Column.Field.FieldName) = 'OBSOLETE')) then
begin
if Column.Field.Value = True then
sText := 'Yes'
Else
If Column.Field.Value = False Then
sText := 'No'
Else
sText := '';
(Sender as TDBGrid).Canvas.FillRect(Rect);
(Sender as TDBGrid).Canvas.TextRect(Rect, Rect.Left+3, Rect.Top+2, sText);
end
Else
Begin { I added this to draw all other columns as defaultdrawing is off }
(Sender as TDBGrid).defaultdrawcolumncell(Rect, DataCol, Column, State);
End;
end;
Respondido el 10 de Septiembre de 13 a las 06:09
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas delphi tdbgrid or haz tu propia pregunta.
Utilice el depurador para descubrir el origen del problema. ¿Ya está dibujado el texto no deseado cuando ingresa este controlador de eventos? Si es así, entonces necesita hacer un mejor trabajo encubriéndolo. De lo contrario, debe encontrar dónde se dibuja y luego determinar qué condición debe efectuar para suprimir esa pintura posterior. En cuanto a sus problemas de enfoque y selección, preste atención a las
State
parámetro. - Rob Kennedygracias roberto Me tomó bastante tiempo, pero como puede ver en la respuesta que publiqué. Eventualmente lo descubrí. También quiero agradecer a todos por las otras respuestas a continuación. Son mucho más elegantes que redibujar; sin embargo, tengo planes más grandes para esta técnica y debo aceptar mi propia solución. Mi pregunta principal era cómo evito que DBGrid dibuje mis cambios. De nuevo, gracias a todos. - Mike