Search code examples
delphitcxgrid

Allow only Negative number in CXGrid


Im working in Delphi 2006 with devexpress.

I have a cxGrid. I want to restrict the entry of values for a negative number column,

my probleme is how can I test the position of '-' when adding it the cell

Is some simple way to allow only negative number in the cell of cxgrid.

thanks in advance


Solution

  • The eaiest way to do what you want is to use a MaskEdit in the grid cell, but as you've said in a comment that you'd prefer not to use one, I've moved how to do that to the end of this answer.

    You and control the user's editing of the cell text entirely in your own code, and I'll show you how to do that.

    By default, if you type a letter key into an cxGrid column for an integer field, you hear a beep. That happens as a result of the key causing TField.IsValidChar(InputChar: Char) for the Integer field linked to the cell to return False.

    If you want to deal with "wrong" keys like that yourself, without using a MaskEdit, you can do it in the EditKeyPressed event. The code below shows that you can do your own enforcement of what the user can enter in the field without having to resort to simulating editing-key presses like you quoted in a comment below. Please note the comments in the code carefully.

    procedure TForm1.cxGrid1DBTableView1EditKeyPress(Sender:
        TcxCustomGridTableView; AItem: TcxCustomGridTableItem; AEdit:
        TcxCustomEdit; var Key: Char);
    var
      AField : TField;
      strValue : String;
      V : Variant;
      i,
      InsertPoint,
      EC : Integer;
    
      function CharIsOK(Ch : Char) : Boolean;
      begin
        Result := CharInSet(Ch, ['0', '1', '2', '3', '4', '5', '6',
                            '7', '8', '9', '-', '+']);
        // Or Result := Ch in ['0', ... for Delphi prior to D2009
      end;
    
    begin
      if AItem = cxGrid1DBTableView1Value then begin
        //  The following manually cleans up input into a TIntegerField column
        // whose Properties is set to TextEdit
    
        // First, pick up the text in the inplace editor
        V := AEdit.EditingValue;
        if not VarIsNull(V) then
          strValue := AEdit.EditingValue
        else
          strValue := '';
    
        if strValue <> '' then begin
          //  Next, check that the Key is a valid one for an Integer field.
          if CharIsOk(Key) then begin
          //  The fact that the Key is a valid character for an Integer field
          //  does not in itself guarantee that the entire editing string, including the Key
          //  which is about to be added to in, is a valid string representation of an integer,
          //  e.g. it might be '--', '+1-5', etc
          //  So, we add the Key to the existing editing string and see if it converts to an integer
          //  Of course, there is the wrinkle that the caret may not be at the end of the editing text
          //  so we need to find out where the caret is.  First we need 
          //  to check that AEdit is a TcxtextEdit so that we can access
          // its SelStart property
            Assert(AEdit is TcxTextEdit);
            InsertPoint := TcxTextEdit(AEdit).SelStart;
            Insert(Key, strValue, InsertPoint + 1);
            Val(strValue, i, EC);
            //  if EC is non-zero, the conversion failed, so we suppress the Key
            if EC <> 0 then
              Key := Chr(0);
           end
           else
             //  the Key might be a backspace, so permit that
             if Ord(Key) <> VK_Back then
               Key := Chr(0);
        end
      end;
    end;
    

    Of course, if you actually want to achieve what you state in the title of your q, namely only allow negative numbers, you can make a trivial change to this code to require that the editing text starts with a minus sign (and the editing text + Key converts to an integer if the editing text is not empty).

    Btw, this code answers your query "how can I get the string value in onpresskey ?" of course.

    To use a MaskEdit in the cxGrid cell, select the cxGrid column in the Object Inspector, then

    • Go to its Properties entry in the OI

    • Select Mask Edit from the drop-down list

    • Set the edit mask for a negative number. See the Online Help if you need help to do this: basically, you enter a minus sign followed by a number of 9s.

    Then, the user can only enter a negative number and can't edit out the leading minus sign.