【问题标题】:accessing controls created by CreateChildControls()访问由 CreateChildControls() 创建的控件
【发布时间】:2012-05-26 02:17:48
【问题描述】:

我需要从另一个类访问由 CreateChildControls() 创建的控件,这样当我选择文件时,我就可以在字符串上找到要引用的路径。

我已经尝试了Accessing controls created dynamically (c#)Problem in accessing dynamically created controls 中的解决方案,但没有任何乐趣,谢谢

    publicTextBox txtUrl; 

    protected override void CreateChildControls()
    {
        Label lblUrl = new Label();
        lblUrl.ID = "lblUrl";
        lblUrl.Text = "Url: ";
        Controls.Add(lblUrl);

        TextBox txtUrl = new TextBox();
        txtUrl.ID = "txtUrl";
        Controls.Add(txtUrl);

        AssetUrlSelector picker = new AssetUrlSelector();
        picker.ID = "ausUrl";

        picker.DefaultOpenLocationUrl =  OpenUrl;
        picker.AssetUrlClientID = txtUrl.ClientID;
        picker.AssetUrlTextBoxVisible = false;
        Controls.Add(picker);

        Control control = Page.LoadControl(_ascxPath);
        Controls.Add(control);

    }

从另一个类我应该能够访问文本框

   protected void Button1_Click(object sender, EventArgs e)
    {
        AssetPicker asspi = new AssetPicker();

        string aaa = asspi.txtUrl.Text;



    }

【问题讨论】:

    标签: c# sharepoint-2010


    【解决方案1】:

    我必须将控件公开,以便其他类可以访问。但它会返回空引用错误。我已经更新了最初的帖子

    如果您公开公开您的子控件,您需要在每个公开公开的子控件的 getter 中调用 EnsureChildControls。这将强制执行CreateChildControls,从而构建您的控制树,确保调用者不会获得空引用。

    例如:

    public Button MyChildButton
    {
        get
        {
            EnsureChildControls();
            return _myChildButton;
        }
    }
    private Button _myChildButton;
    
    ...
    
    protected override void CreateChildControls()  
    {
        ...
        _myChildButton = new Button();
        ... 
    }
    

    请注意,为了做到这一点,您需要将您的子控件公开为属性,而不是字段。 IE。在您的示例代码中,您需要替换:

    public TextBox txtUrl;  
    

    作者:

    public TextBox TxtUrl
    {
        get
        {
            EnsureChildControls();
            return txtUrl;
        }
    }
    private TextBox txtUrl;
    

    您还应该从CompositeControl 继承,它对Controls 属性做了类似的事情:

    public override ControlCollection Controls
    {
        get
        {
            EnsureChildControls();
            return base.Controls;
        }
    }
    

    如果由于某种原因您没有从 CompositeControl 继承,那么您需要将此 Controls 覆盖添加到您的类中。

    顺便说一句,公开子控件可能会给调用者提供太多信息,而调用者可能不应该关心这些实现细节。相反,您可以只公开您的子控件的相关属性。例如,您可以公开字符串属性 Url,而不是公开子 TextBox TxtUrl

    public string Url
    {
        get
        {
            EnsureChildControls();
            return txtUrl.Text;            
        }
        set
        {
            EnsureChildControls();
            txtUrl.Text = value;
        }
    }
    

    【讨论】:

    • 您好,感谢您的 enser 我尝试了第二段代码,它现在返回一个警告:txtUrl 从未分配给并且将始终具有其默认值 null
    • “永远不会分配给它,并且将始终具有其默认值 null” - 在这种情况下,您需要分配它,您应该在 CreateChildControls 方法中执行 - “txtUrl = new TextBox();”等等...而不是“TextBox txtUrl = new TextBox();”
    【解决方案2】:

    最后,当您将静态控件添加到页面时,.NET 会做什么,它会将控件的引用作为字段保存(它们通常转到 .designer 文件)。因此,只需以相同的方式将控件作为字段:

    private Label lblUrl;
    private TextBox txtUrl;
    private AssetUrlSelector picker;
    private Control control;
    
    protected override void CreateChildControls()
    {
        lblUrl = new Label();
        lblUrl.ID = "lblUrl";
        lblUrl.Text = "Url: ";
        Controls.Add(lblUrl);
    
        txtUrl = new TextBox();
        txtUrl.ID = "txtUrl";
        Controls.Add(txtUrl);
    
        picker = new AssetUrlSelector();
        picker.ID = "ausUrl";
    
        picker.DefaultOpenLocationUrl =  OpenUrl;
        picker.AssetUrlClientID = txtUrl.ClientID;
        picker.AssetUrlTextBoxVisible = false;
        Controls.Add(picker);
    
        control = Page.LoadControl(_ascxPath);
        Controls.Add(control);
    }
    

    【讨论】:

    • 另外,如果您需要以通用方式与“控件”交互,您可以使所有可能存在的控件继承相同的基类,该基类将提供所需的交互接口。
    • 谢谢我已经尝试过了,尽管我必须将控件公开才能从另一个班级访问。但它会返回空引用错误。我已经更新了最初的帖子
    • 问题是您在调用 CreateChildControls 之前访问控件。您需要对控件做什么?也许您必须等待控件或页面的另一个事件才能访问它们。另外,我建议不要公开控件,而只公开您必须使用的控件(不要与陌生人交谈模式)
    • 控件在 sharepoint 中选择一个路径并将其返回到我可以看到填充了路径的文本框。那么我需要访问该路径才能使用该字符串并执行其他操作。
    • 您在哪种情况下访问该信息?它必须是在 CreateChildControls 之后触发的事件。我建议Load 甚至Textbox.TextChanged 来确定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 2011-02-28
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    相关资源
    最近更新 更多