Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何检测ASP.NET控件属性是否包含数据绑定表达式?_C#_Asp.net_Data Binding_Custom Controls - Fatal编程技术网

C# 如何检测ASP.NET控件属性是否包含数据绑定表达式?

C# 如何检测ASP.NET控件属性是否包含数据绑定表达式?,c#,asp.net,data-binding,custom-controls,C#,Asp.net,Data Binding,Custom Controls,我有一个自定义控件,它继承自System.Web.UI.control,它的一些属性可以使用数据绑定表达式进行声明性设置。e、 g <foo:Foo runat="server" MyFoo="<%# this.GetFoo() %>" /> 现在,当我这样做时,我需要调用控件(或其父控件之一)上的.DataBind(),以计算这些表达式 我想能够做的是检测是否有任何属性是以这种方式设置的,然后在OnPreRender之后自动调用自定义控件this.DataBind

我有一个自定义控件,它继承自
System.Web.UI.control
,它的一些属性可以使用数据绑定表达式进行声明性设置。e、 g

<foo:Foo runat="server" MyFoo="<%# this.GetFoo() %>" />

现在,当我这样做时,我需要调用控件(或其父控件之一)上的
.DataBind()
,以计算这些表达式

我想能够做的是检测是否有任何属性是以这种方式设置的,然后在
OnPreRender
之后自动调用自定义控件
this.DataBind()
,或者在那里

那么问题就来了:如何检测数据绑定表达式是否正在等待执行

我确信在一些
ControlBuilder
DataBindContext
类中,存在着确定这一点所需的信息。我用反射器四处搜寻,似乎找不到它


我应该补充一点,如果没有以这种方式分配直接属性,我不想支付执行
DataBind()
的开销。这就是为什么我想在手之前检测。这个类非常轻,但我希望能够声明性地设置属性,而不需要任何代码。

ControlBuilder
类上有一个名为
SubBuilders
内部数组列表。对于每个数据绑定表达式
TemplateParser
enocunters,
ProcessCodeBlock()
添加一个
CodeBlockBuilder
对象,该对象具有
BlockType
属性
CodeBlockType.databinding
SubBuilder

因此,如果您可以获得所需的
ControlBuilder
的句柄,您应该能够反射式地迭代
子生成器
,并查找类型为
CodeBlockBuilder
的对象,其中
BlockType==CodeBlockType.DataBinding


请注意,这当然是各种令人讨厌的,我真的怀疑这是解决你核心问题的最好方法。如果你后退两步,看看原来的问题,也许可以把它贴在Stackoverflow上——有很多超级聪明的人可以帮助你想出一个好的解决方案。

深入了解
ControlBuilder
,我注意到,当存在数据绑定表达式时,每个控件实例的编译工厂将附加一个
数据绑定
事件处理程序。我发现,检查这一点似乎是确定是否需要进行数据绑定的一种非常可靠的方法。以下是我解决问题的基础:

using System;
using System.Reflection;
using System.Web.UI;

public class AutoDataBindControl : Control
{
    private static readonly object EventDataBinding;
    private bool needsDataBinding = false;

    static AutoDataBindControl()
    {
        try
        {
            FieldInfo field = typeof(Control).GetField(
                "EventDataBinding",
                BindingFlags.NonPublic|BindingFlags.Static);

            if (field != null)
            {
                AutoDataBindControl.EventDataBinding = field.GetValue(null);
            }
        }
        catch { }

        if (AutoDataBindControl.EventDataBinding == null)
        {
            // effectively disables the auto-binding feature
            AutoDataBindControl.EventDataBinding = new object();
        }
    }

    protected override void DataBind(bool raiseOnDataBinding)
    {
        base.DataBind(raiseOnDataBinding);

        // flag that databinding has taken place
        this.needsDataBinding = false;
    }

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);

        // check for the presence of DataBinding event handler
        if (this.HasEvents())
        {
            EventHandler handler = this.Events[AutoDataBindControl.EventDataBinding] as EventHandler;
            if (handler != null)
            {
                // flag that databinding is needed
                this.needsDataBinding = true;

                this.Page.PreRenderComplete += new EventHandler(this.OnPreRenderComplete);
            }
        }
    }

    void OnPreRenderComplete(object sender, EventArgs e)
    {
        // DataBind only if needed
        if (this.needsDataBinding)
        {
            this.DataBind();
        }
    }
}
如果未连接
数据绑定
事件处理程序,或者控件手动绑定数据(直接或通过父控件),则此解决方案将禁用自身


请注意,这段代码中的大部分只是为了能够测试事件的存在而跳转。唯一需要的反射是一次性查找,以获取用作
事件数据绑定的键的
对象

为什么不在代码隐藏中简单地按Page.DataBind()进行绑定?!它将绑定该页面中的所有控件,而不重新标记它们是什么。。。请看:正如我在问题中所说的,如果不需要,我不想支付执行DataBind()的开销。这就是最初的问题:有时会出现数据绑定表达式,如果不必添加代码,我希望不必在后面添加代码,这意味着控件本身应该调用
DataBind
,我不想让性能损失总是
DataBind
ing。我正在浏览
System.Web.UI.WebControls.BaseDataBoundControl
是如何知道自动绑定的,但我认为它的方式对于这个简单的需求来说太笨重了。我想要实际的绑定信息,而不是像他们那样跟踪。听起来实际的信息可能会更昂贵(反射),但我会先检查一下。谢谢