【问题标题】:Are there any way to use delphi inputbox with multiple values?有没有办法使用具有多个值的delphi输入框?
【发布时间】:2009-12-10 08:20:05
【问题描述】:

我想从用户那里获取多个不同类型的值(时间、压力、姓名……)。我想自定义我的输入框。但它只取一个值。

有什么办法可以解决这种情况,或者有什么组件可以使用吗?

【问题讨论】:

    标签: delphi inputbox multiple-value


    【解决方案1】:

    弗朗索瓦是对的。你已经达到了你得到的工具的极限。 InputBox 根本不是为复杂输入而设计的,也不是为了处理多个值而设计的。

    The page you linked to 在你的评论中有一个例子,但它的表现相当糟糕,所以我不怪你误解了它。我也读了几本书才明白。它的核心是底部的MyAsk 函数。 (忽略顶部的TAppendThread 类声明。它没用。)MyAsk 接受带有提示和值的记录列表,并且对于每条记录,它调用InputBox 以向用户请求一个值。没有记录可能更容易理解。可以这样改写:

    procedure MultiInputBox(const Prompts: array of string; var Values: array of string]);
    var
      i: Integer;
    begin
      Assert(Length(Prompts) = Length(Values));
      for i := 0 to High(Prompts) do begin
        Values[i] := InputBox(Application.Title, Prompts[i], Values[i]);
      end;
    end;
    

    这样称呼它:

    TempTime := TimeToStr(DefaultTime);
    TempPressure := IntToStr(DefaultPressure);
    TempName := DefaultName;
    MultiInputBox(['Time', 'Pressure', 'Name'], [TempTime, TempPressure, TempName]);
    TimeToUse := StrToTime(TempTime);
    PressureToUse := StrToInt(TempPressure);
    NameToUse := TempName;
    

    这对于用户来说是一个糟糕的界面。没有办法回去,没有办法取消,没有迹象表明询问将持续多长时间,也没有办法强制某些数据类型的格式。如果您设计一个能够准确获取所需信息的自定义表单,您的情况会好得多。您正在使用一种工具来设计一个关于世界上最简单的事情的表单。不要抗拒。

    如果您需要获取时间、压力和名称,则制作一个带有三个输入控件的表单。使用TDateTimePicker 作为时间,考虑使用TSpinEdit 作为数字输入,使用TEdit 作为名称。在每个输入旁边放置TLabel 控件,以便用户知道每个输入的用途。将确定和取消按钮放在表单上。设置各种其他表单属性,例如边框样式和标题。几乎没有代码可以写成那种形式。不过,您可以随意添加代码来验证输入值,以确保它们有意义。

    要使用它,只需创建它、填充其初始值、以模态方式显示它,并在它关闭时读出新值。

    var
      form: TDatePressureNameDialog;
    begin
      form := TDatePressureNameDialog.Create(nil);
      try
        form.TimePicker.Value := DefaultTime;
        form.PressureEdit.Value := DefaultPressure;
        form.NameEdit.Text := DefaultName;
        if form.ShowModal = mrOK then begin
          TimeToUse := Frac(form.TimePicker.Value);
          PressureToUse := form.PressureEdit.Value;
          NameToUse := form.NameEdit.Text;
        end;
      finally
        form.Free;
      end;
    end;
    

    还要注意我是如何检查ShowModal 方法的结果的。这让您知道用户是否按下了确定或取消来关闭表单。 InputBox 无法做到这一点,它总是返回一个字符串。 (InputQuery 可以告诉您这些信息,这是这两个函数之间的主要区别,但仅此一点并不能真正使这两个函数在您的情况下值得使用。)

    不用担心这个新的表单类会影响您的项目。对项目规模影响最大的两件事是 SysUtilsForms 单元。你已经包括了那些,所以最糟糕的已经过去了。将表单添加到已经至少有一个表单的项目中根本不会影响项目大小,尤其是我上面描述的表单,它只有八个控件。

    【讨论】:

      【解决方案2】:

      “输入框”到底是什么意思 - 一个 TEdit?有许多不同种类的输入组件,它们可以做许多不同的事情。对于名称,TEdit 非常好 - 但对于时间,您可能需要一个日历控件,对于压力,您可能希望使用一个看起来非常适合数字的控件。

      【讨论】:

        【解决方案3】:

        是的,设计一个表格!

        Dialogs.InputBox 旨在从用户那里获取 1 个字符串,快速而简单。
        如果你想要更多,你必须设计一个参赛表格。
        如果您想要一个基本对话框,您可以查看 Dialogs.InputQuery 中的代码,并将其用作编写您自己的过程的起点。

        如果你想要真正的交易,你必须深入挖掘并编写一个真正的表单。

        【讨论】:

        • 没必要惹讨厌的弗朗索瓦。
        • 谢谢,但我想让我的软件更轻,所以我不想在我的项目中添加任何表单。我找到了一个例子,但很难理解.. :( delphipages.com/forum/showthread.php?t=154839
        • 我想我太累了,没有注意到它可以被解释为我现在看到的......已更改。
        • @Rapunzo:如果您的项目中已经有许多表单,那么额外的一个不会有太大的不同。只要确保根据它的使用方式对其进行适当的管理。 IE。在启动时创建还是按需创建?保留它还是在每次使用时重新创建它?允许多个实例还是只允许一个? .....也就是说,如果你真的在追求一个极轻量级的应用程序,Delphi 可能不是最好的选择;但在 99% 的情况下,开销相对微不足道,而您获得的好处使这一切都值得。 (参见 Rob Kennedy 的回答)
        【解决方案4】:

        Rob 的 Kennedy 是对的。输入框不是一个好的选择... 你到底想保存什么? Exe 空间、资源或源代码?或者你只是想用你的“绿色”代码来拯救环境?

        如果您看一下 InputQuery 函数,您会发现它所做的是创建一个 TForm 并创建一些 TButtons/TLabels/TEdit,定位并显示模态表单。

        您将如何处理添加到项目中的新表单......除此之外,您还可以验证、自定义控件并定位它们,甚至添加提示......

        使用新表格...

        【讨论】:

          【解决方案5】:

          您不必将每个表单都设置为自动创建,创建表单后进入项目选项,选择表单选项并将所有您不希望自动创建的表单移到右侧。

          我最常用于这些非自动创建表单的模式如下:

          Function GetValuesFromDialog : boolean;
          var
            dlg : tValuesDialog;
          begin
            result := false;
            dlg := tValuesDialog.Create(nil);  
            try
              // set initial values in dialog
              dlg.SetValues( rData );
              // show the dialog
              result := dlg.ShowModal = mrOk;
              // pull values from dialog
              if result then
                dlg.GetValues( rData );
            finally
              dlg.free;
            end;
          end;
          

          GetValues/SetValues 方法从保存例程中使用的值的记录或类填充对话框。我从不尝试从表单外部操作表单上的控件,而是编写例程在表单本身中进行操作。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-02
            • 1970-01-01
            • 1970-01-01
            • 2020-05-06
            • 2011-11-20
            • 2022-07-07
            相关资源
            最近更新 更多