GVKun编程网logo

Delphi Win32:加速动态创建的控件(父属性)(delphi动态创建按钮)

15

在本文中,我们将为您详细介绍DelphiWin32:加速动态创建的控件(父属性)的相关知识,并且为您解答关于delphi动态创建按钮的疑问,此外,我们还会提供一些关于.net–动态创建的控件未触发事件

在本文中,我们将为您详细介绍Delphi Win32:加速动态创建的控件(父属性)的相关知识,并且为您解答关于delphi动态创建按钮的疑问,此外,我们还会提供一些关于.net – 动态创建的控件未触发事件处理程序、asp.net – 如何验证动态创建的控件?、c# – 使用动态创建的控件重复Lambda代码吗?、c# – 获取asp.net中动态创建的控件的属性值的有用信息。

本文目录一览:

Delphi Win32:加速动态创建的控件(父属性)(delphi动态创建按钮)

Delphi Win32:加速动态创建的控件(父属性)(delphi动态创建按钮)

我们有几个框架的GUI,可动态构建其内容.每个框架都会创建面板,标签,编辑,组合框等,以用作输入字段.这非常有效,我们还计划让每个框架在不同的线程中构建其内容.

但是有一个大问题:它很慢!创建控件不需要花时间,但设置Parent属性似乎非常耗时.

我已经尝试了几种方法来加快这个过程,但没有运气.我尝试过Enabled = False,Visible = False,disableAlign,LockWindowUpdate,WM_SETREDRAW ……但似乎没有任何事情影响设置控件的Parent的耗时过程.

即使我们使用线程,这也需要时间,因为必须在Synchronize中调用VCL函数.

有没有其他方法可以加快控件的创建和显示速度?

亲切的问候,
马格努斯

编辑:没有数据感知组件或GUI中触发的任何事件.我只是创建控件并显示它们.使用计时器我已经确定控件父(AControl.Parent:= AOwner)的分配是耗时的部分.

编辑2:如下面的答案所示,速度问题不是设置父级而是绘制控件.当我测试时间时,容器是可见的并且设置父级导致立即绘制控件.

编辑3:动态GUI的另一个耗时部分是将项目分配给组合框. ComboBox.Items.Assign(DataItems),其中DataItems不超过三到六个项目.

谢谢大家抽出时间帮助我!

解决方法

不要尝试使用多个线程来创建控件,也不要尝试使用VCL.这无论如何都不会提高速度,但更重要的是与VCL完全禁止.

编辑:您应该在StackOverflow上阅读处理VCL和多个线程的其他问题和答案,但简而言之:VCL不是线程安全的,所有对控件的访问都必须在主线程的上下文中完成.因此,当使用多个线程时,您必须在Synchronize()调用中包装几乎所有内容,这实际上会序列化所有线程并进一步降低速度.

最好的办法是重新构建UI,这样就不需要一次创建它.只有在第一次显示所有帧时才按需创建所有帧.

编辑2:这是一些测试代码,表明设置Parent属性不是真正的问题,但创建所有控件(包含所有需要的消息处理)可能是.

procedure TForm1.Button1Click(Sender: TObject);
var
  i,j,x,y: integer;
  Edit: TEdit;
  Ticks: LongWord;
begin
  Visible := FALSE;
  DestroyHandle;

  try
    for i := 1 to 20 do begin
      y := 20 + i * 25;
      for j := 1 to 10 do begin
        x := (j - 1) * 100;

        Edit := TEdit.Create(Self);
        Edit.SetBounds(x,y,98,23);
        Edit.Parent := Self;
      end;
    end;
  finally
    Ticks := timeGetTime;
    Visible := TRUE;
    Caption := IntToStr(timeGetTime - Ticks);
  end;
end;

在释放父窗体的句柄后,代码动态创建200个TEdit控件.在我的系统上创建所有这些控件并设置它们的属性需要几十毫秒,但最后显示表单(将创建所有窗口)需要几百毫秒.由于这只能在主线程中完成,我怀疑使用多线程会对你有所帮助.

.net – 动态创建的控件未触发事件处理程序

.net – 动态创建的控件未触发事件处理程序

我有动态创建的TextBox的这个问题.

当在PageLoad中创建TextBox时,它被TextChanged事件触发.
但是当我动态地删除并重新创建了TextBox时,TextChanged没有触发.

这是代码:

的.aspx

<body>
    <form id="form1" runat="server">
    <div>

    <asp:Table ID="Table1" runat="server">
      <asp:TableRow>
        <asp:TableCell ColumnSpan="2">Fixed content</asp:TableCell>
      </asp:TableRow>
    </asp:Table>   
    </form>
</body>

的.cs
public partial class test:System.Web.UI.Page
{
string myText =“a”;

protected void Page_Load(object sender,EventArgs e)
  {
    WriteRows();
  }

  private void WriteRows()
  {
    TableRow tr = new TableRow();

    TableCell tc = new TableCell();
    TextBox txt = new TextBox();
    txt.Text = myText;
    txt.TextChanged += new EventHandler(txt_TextChanged); // Assign event handler
    tc.Controls.Add(txt);
    tr.Controls.Add(tc);

    tc = new TableCell();
    tc.Text = txt.Text;
    tr.Controls.Add(tc);

    Table1.Controls.AddAt(1,tr);
  }

  private void txt_TextChanged(object sender,EventArgs e)
  {
    myText = ((TextBox)sender).Text;
    RedrawTable(); // Delete the row (incl. the TextBox) and rewrite it
  }

  private void RedrawTable()
  {
    Table1.Controls.RemoveAt(1);
    WriteRows();
  }
}

有没有人有解决方案,以便事件总是被触发?

解决方法

事件处理由ASP.NET通过匹配控件的ID&请求参数.在您的情况下,在txtTextChanged()期间创建的TextBox将具有自动ID,因为您没有指定任何显式ID.该文本更改事件期间该ID将被发回.

在页面加载事件之后,ASP.NET将尝试找到具有此ID的控件来触发事件.显然,ASP.NET将无法找到匹配,因为在Page_Load()中创建的TextBox是不同的,并且具有不同的ID.

要解决这个问题:为你的文本框指定一个显式的ID:

TextBox txt = new TextBox();
txt.Text = myText;
txt.ID = "txtBox";

asp.net – 如何验证动态创建的控件?

asp.net – 如何验证动态创建的控件?

我有一个asp.net页面,它的一些控件是动态创建的,这些控件是以下之一;文本框,日历或下拉列表.

在某些情况下,这些控件应该根据从db读取的标志进行验证吗?

Is there any way to validate
dynamically created controls?

解决方法

基本上,您需要通过代码创建验证器,并通过代码将它们附加到动态创建的控件上.然后,页面将使用页面中的验证器为您呈现.

如果验证需要从db读取标志,那么可能使用自定义验证器,这将允许您在客户端和服务器上设置特定逻辑以满足特定的验证要求.如果您不想,则不必提供客户端验证.

c# – 使用动态创建的控件重复Lambda代码吗?

c# – 使用动态创建的控件重复Lambda代码吗?

今天我回答了 question,基本上是关于UI交互.但后来它让我想到了OP用他们的代码编写动态创建的控件的方式.

错过了.Net 2-4并且现在才学习’新’的东西,这实际上是让我在第一个地方问题的原因..:

private void AddPieceButton_Click(object sender,EventArgs e)
{
   somePieceControl newPiece = new somePieceControl ();
   //..
   newPiece.MouseDown += (sender2,evt) =>  { /* 1st block of code */ };
   newPiece.MouseUp   += (sender2,evt) =>  { /* 2nd block of code */ };
   newPiece.MouseMove += (sender2,evt) =>  { /* 3rd block of code */ }
   //..
   someContainer.Controls.Add(newPiece);
}

在测试案例中,问题几乎不重要;但代码块可以很容易地获得更多,更大;在像Go这样的游戏中,最终会有数百个游戏作品.

虽然人们可能/可能并且应该质疑添加如此多控件的想法,但是询问思想仍然想要知道……:每个部分都有自己的代码块副本,因为我猜它已经或者它们在我们的世界中被考虑在内像正常事件一样的奇迹,只在运行时记忆中只活一次?

解决方法

每个lambda在编译时都会转换为“普通”方法,因此lambas的实际代码不会重复.但是,每次运行此方法时,将实例化引用代码的新EventHandler委托.

c# – 获取asp.net中动态创建的控件的属性值

c# – 获取asp.net中动态创建的控件的属性值

我如何确定一些动态创建的asp.net控件的宽度?
例如,我有这样的代码:

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<encosia:HighslideManager ID="HighslideManager1" runat="server" FadeInOut="true"
    OutlineType="RoundedWhite" ControlBar="false" />
<table>
    <tr>
        <td valign="top"https://www.jb51.cc/tag/ott/" target="_blank">otted 2px White;">
            <asp:literal id="litText" runat="server" mode="Passthrough"></asp:literal>
        </td>
        <td valign="top">
            <tablecellspacing="10">
                <tr>
                    <td valign="top"id="imageTD" runat="server"  oninit="imageTD_OnInit">
                        <asp:literal id="litEmptyText" runat="server" mode="Passthrough"></asp:literal>
                        <asp:repeater id="Repeater1" runat="server">
                            <ItemTemplate>
                                <center>
                                    <encosia:HighslideImage ID="HighslideImage1" runat="server" Width="200px"
                                            ImageUrl='<%# Eval("ImageURL","images/images/{0}") %>'
                                            FullImageURL='<%# Eval("ImageURL","images/images/{0}") %>'
                                            AlternateText='Image <%# Container.ItemIndex%>'/>


                                    <asp:Label ID="imageDescriptionLabel" 
                                         runat="server" CssText= '<%# CutimageDescText(String.Format("{0}",Eval("Description")),imageTD.Width) %>' />
                                </center>
                            </ItemTemplate>
                            <SeparatorTemplate>
                                <%# ((Container.ItemIndex % 2) == 1) ? "</td></tr><tr><td valign=\"top\" style=\"width:50%;\">" : "</td><td valign=\"top\" style=\"width:50%;\">"%>
                            </SeparatorTemplate>    
                        </asp:repeater>
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>

我需要计算imageTD的宽度.
我试图在页面事件中计算它的宽度,但是这个属性也像其他样式属性一样是空的. (((
请帮我!
谢谢!

解决方法

你可以通过以下方式做到这一点:

>如果要使用“td”标记作为服务器,则需要将表标记的“runat”设置为“server”并设置该表的ID
>您还需要设置“服务器和ID”tr和td标签
>如果创建td不进入任何数据绑定控件,如转发器,您可以轻松地从服务器端的此控件获取任何属性

.aspx页面示例

<table runat="server" id="tabl1">
    <tr runat="server" id="tr1">
    <td runat="server" id="td1">

    </td>
    </tr>
</table>

.aspx.cs代码exaple

protected void Page_Load(object sender,EventArgs e)
{
    var h = td1.Width;
}

今天的关于Delphi Win32:加速动态创建的控件(父属性)delphi动态创建按钮的分享已经结束,谢谢您的关注,如果想了解更多关于.net – 动态创建的控件未触发事件处理程序、asp.net – 如何验证动态创建的控件?、c# – 使用动态创建的控件重复Lambda代码吗?、c# – 获取asp.net中动态创建的控件的属性值的相关知识,请在本站进行查询。

本文标签: