• 在FormView控件中嵌套数据绑定控件的问题,以及从一个对象中反射获取属性值的简单办法


    最近研究Entity Framework 4 + ObjectDataSource + FormView的组合。

    问题在于下面这段代码:

    1 <EditItemTemplate>
    2 <sc:NetCheckPolicyDropDownList ID="ddlNetCheckPolicy" runat="server"
    3 SelectedValue='<%#Bind("OverrideNetCheckPolicyID") %>' >
    4 </sc:NetCheckPolicyDropDownList>
    5  </EditItemTemplate>

    在FormView控件的EditItemTemplate模板中,我使用了自定义DropDownList控件,这些DropDownList控件通过调用自己的DataBind方法完成数据绑定加载。同时,利用标准的“Bind”方式设置DropDownList控件的SelectedValue属性,以谋求对DropDownList的双向绑定。

    看上去没什么不妥,但是在运行时报错:

    Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control

    就经过艰苦卓绝地Google和各种分析,原来问题在于,简单地说,执行DropDownList的DataBind时,那个“<%#Bind ... %> ”被当作这个绑定的一部分执行了,但它本来应该是FormView控件绑定时才需要做的。可惜我们能分出来,ASP.NET分不出来。解决的方法有2个:

    1. DropDownList不要采用默认的DataBind方法加载数据,而采用自定义的数据加载。

    2. 手工在FormView的ItemCreated (或者DataBound?)事件中为DropDownList的SelectedValue赋值,并在FormView执行插入或更新的操作时再手工把DropDownList值取出来。

    我采用了第一种方式,在我的DropDownList中加入了新的数据加载方法,基本上套用了反射出来的标准DropDownList控件具体执行绑定数据的操作(代码仅供参考):

    public void DataPopulate()
    {
    	DataPopulate(false);
    }
    
    /// <summary>
    /// Populate the DropDownList control.
    /// </summary>
    /// <param name="usingDataBind">gets or sets a value indicating whether to use the standard DataBind mechanism</param>
    public void DataPopulate(bool usingDataBind)
    {
    	Items.Clear();
    	DataSource = CreateDataSource();
    	if (DataSource == null)
    		return;
    	if (usingDataBind)
    	{
    		DataBind();
    		return;
    	}
    
    	IEnumerable source = DataSource as IEnumerable;
    	if (source == null)
    		throw new InvalidCastException("DataSource must be of type \"IEnumerable\"");
    
    	if (DataTextField.Length == 0)
    		throw new ArgumentNullException("DataTextField");
    	if (DataValueField.Length == 0)
    		DataValueField = DataTextField;
    
    	ICollection sourceCollection = DataSource as ICollection;
    	if (sourceCollection != null)
    		Items.Capacity = sourceCollection.Count + Items.Count;
    
    	ListItem li;
    	foreach (object item in source)
    	{
    		li = new ListItem();
    		li.Text = DataBinder.GetPropertyValue(item, DataTextField, DataTextFormatString);
    		li.Value = DataBinder.GetPropertyValue(item, DataValueField, null);
    		Items.Add(li);
    	}
    	OnDataBound(EventArgs.Empty);
    }
    
    /// <summary>
    /// create a data source object used by DropDownList control
    /// </summary>
    /// <returns>a data source object</returns>
    protected virtual object CreateDataSource()
    {
    	return null;
    }
    

    注意,System.Web.UI.DataBinder类,用这个类可以方便的从一个对象中反射出属性的值,省却了我们自己反射的麻烦。

    最后这也给了我一个启示,对于这种可能将来作为绑定控件内再绑定的自定义控件,还是尽量不要用默认的绑定机制吧,省得出现这种问题。


    理解的越多,需要记忆的就越少
  • 相关阅读:
    Android进阶——Volley+Https给你的安卓应用加上SSL证书(转)
    VSFTP上传不了
    mysql主从同步配置
    EditText插入表情(字符串)到光标所在位置
    js实现监听页面滚动实现图片延迟加载
    android开发技巧——仿新版QQ锁屏下弹窗(转)
    [原创]JAVA技巧:去除ArrayList<Object>里面的重复记录
    [原创]JAVA号码工具类:实现手机固话号码判断与区号截取
    [原创]FreeSWITCH实现多人来电思路
    [原创]Linux实现服务延迟启动
  • 原文地址:https://www.cnblogs.com/Ricky81317/p/2024660.html
Copyright © 2020-2023  润新知