开发者

Delphi: Autoscale TEdit based on text length does not work when removing chars

开发者 https://www.devze.com 2022-12-25 01:40 出处:网络
I have an input edit field where the user can enter data. I want the box width to be at least 191px (min) and maximum 450px (max).

I have an input edit field where the user can enter data. I want the box width to be at least 191px (min) and maximum 450px (max).

procedure THauptform.edtEingabeChange(Sender: TObject);
begin

// Scale
if Length(edtEingabe.Text) > 8 then
    begin
        if Hauptform.Width <= 450 then
            begin
                verschiebung := verschiebung + 9;
                // The initial values like 'oldedtEingabeWidth' are global vars.
                edtEingabe.Width := oldedtEingabeWidth + verschiebung;
                buDo.Left := oldbuDoLeft + verschiebung;
                Hauptform.Width := oldHauptformWidth + verschie开发者_如何学Cbung;
            end;
    end;
end;

This works for ENTERING text. But when I delete one char, it does not scale back accordingly.


In your code, nothing will happen when your text is less than 8 characters long.

Also, I don't see any condition under which your width becomes smaller. It only becomes larger (by 9) with each iteration.

By the way, you appear to be multiplying by 9 as an average character width. You can use Canvas.TextWidth to determine the actual width required by the text without estimating.

If you want to use "9" anyway, you should name it as a constant to make clear what it is.

Quick and dirty using TextWidth:

const
   MAX_EINGABE_WIDTH = 450;
   MIN_EINGABE_WIDTH = 191;

procedure THauptform.edtEingabeChange(Sender: TObject);
var Width: Integer;
begin

    // Scale
    Width := edtEingabe.Canvas.TextWidth(edtEingabe.Text);
    if Width > MAX_EINGABE_WIDTH then
       Width := MAX_EINGABE_WIDTH
    else if Width < MIN_EINGABE_WIDTH then
       Width := MIN_EINGABE_WIDTH

    edtEingabe.Width := Width;

end;


You're just adding 9 everytime the text changes and the length is grater than 8 - regardless of the change. You need to make it a function based on the length instead.

Something like this would do the trick:

procedure THauptform.edtEingabeChange(Sender: TObject); 
var
  len: integer;
  additionalWidth: integer;
begin
  len := Length(edtEingabe.Text);
  if len <=8 then
    additionalWidth:=0
  else
    additionalWidth:=(len-8)*9; //Assuming we need an extra 9 pixels per character after the 8th one
  if additionalWidth > 259 then additionalWidth := 259; // maximum - minimum

  edtEingabe.Width := 191 + additionalWidth;
  Width := OriginalFormWidth + additionalWidth; // You'll need to know what the minimum width of your form is
end;

This isn't really a very pretty solution, though - changing all of those properties in the same way is ugly. Instead, since it appears you're also resizing the form, you can change the Anchors property of your edit box to make it maintain its margin to the right side as well, and only resize your form.

However, you probably want to consider if this is really a good idea. Why not let the input field just have a single size? In general, it looks better if windows don't resize on their own.


Do something like this:

procedure THauptform.edtEingabeChange(Sender: TObject);
var
  Edit:TEdit;
begin
  Edit := TEdit(Sender);
  Edit.Width := Canvas.TextWidth(Edit.Text+' |')+
                  Edit.Padding.Left+
                  Edit.Padding.Right;
end;
  • Note 1: Don't manually try to limit the size. Instead, set Constraints.MinWidth and Constraints.MaxWidth via the property editor. That leaves your code clean and useless GUI stuff like this in the .dfm.

  • Note 2: TEdit doesn't have any public canvas property that you can use to get the text width.

  • Note 3: I don't like this kind of interface with growing and shrinking inputs, but it's probably just a matter of personal taste.

0

精彩评论

暂无评论...
验证码 换一张
取 消