自定义模板化asp.net控件的双向数据绑定这道题本来是关于双向绑定工作的,但是由于没有具体的答案和其他发展,我一直在更新它——你可以查看编辑历史,但我认为这样更清晰。下面的代码清单允许将单个对象双向数据绑定到模板化控件。我想以最简单的方式扩展此示例,以允许为最根对象的复杂类型属性嵌套类似的启用双向数据绑定的模板控件。例如,SampleFormData具有属性ListItems。我希望能够在最基本的模板(来自此代码清单)中绑定到此列表,并在可编辑的文本框列表中显示字符串数据,可能带有用于插入、删除、重新绑定输入更改的命令(返回List属性绑定对象)。此外,如果这是一个复杂类型的列表(SampleFormChildData,而不是字符串),SampleSpecificEntryForm可以在列表中使用一个新的嵌入的SampleSpecificEntryForm,绑定到每个列表的项目,就像一个转发器。依此类推留下简单的属性,如果作者这样选择的话。ui-fields不需要自动生成,仅用于绑定。注意:List的特殊之处在于,即使是内置绑定也不能直接将字符串作为DataItems处理——直接绑定到字符串作为列表中的项目不是必需的,但肯定是有价值的。这与FormView的不同之处在于,它不是为了期望绑定到项目列表中的一个而构建的,而只是作为单个项目在视图状态中持久存在。与FormView不同的是,它只有一个类似于FormView的EditTemplate的默认模板。同样,绑定到类集合属性的属性只有一个视图——编辑。没有选择然后编辑的行。一切都是可编辑的。目的是使双向绑定表单更易于构建。在我看来,应该有两个绑定。SingleEntityBinding和CollectionBinding。SingleEntityBinding将单个对象实例作为数据源(原型为SampleSpecificEntryForm),而CollectionBinding可以绑定到具有属性DataSourceID="EntryForm1"DataMember="Items"的父SingleEntityBinding,如下面DataList1的代码示例所示。两种类型都应支持任一类型的嵌套。表单作者有责任对支持对象的数据执行列表操作,例如插入/更改/删除类型操作;然而,这种机制实施起来相对简单。这是一些代码,希望它对某人有所帮助。200分是为了达到这个布局目标的最佳建议……usingSystem.ComponentModel;使用System.Collections.Specialized;使用System.Collections.Generic;namespaceSystem.Web.UI.WebControls.Special{[Serializable]publicclassSampleFormData{publicstringSampleString{get;放;}publicintSampleInt{得到;放;}公共列表项{get;放;}publicSampleFormData(){SampleString="样本字符串数据";示例Int=5;项目=新列表();}}[ToolboxItem(false)]publicclassSampleSpecificFormDataContainer:WebControl,INamingContainer,IDataItemContainer{SampleSpecificEntryFormentryForm;内部SampleSpecificEntryFormEntryForm{get{returnentryForm;}}[Bindable(true),Category("Data")]publicstringSampleString{get{returnentryForm.FormData.SampleString;}set{entryForm.FormData.SampleString=value;}}[Bindable(true),Category("Data")]publicintSampleInt{get{returnentryForm.FormData.SampleInt;}set{entryForm.FormData.SampleInt=值;}}[Bindable(true),Category("Data")]publicListItems{get{returnentryForm.FormData.Items;}set{entryForm.FormData.Items=value;}}internalSampleSpecificFormDataContainer(SampleSpecificEntryFormentryForm){this.entryForm=entryForm;}#regionIDataItemContainer成员publicobjectDataItem{get{returnentryForm.FormData;}}publicintDataItemIndex{得到{返回0;}}publicintDisplayIndex{得到{返回0;}}#endregion}publicclassSampleSpecificEntryForm:DataBoundControl,INamingContainer,IDataSource{#region模板privateIBindableTemplateformTemplate=null;[Browsable(false),DefaultValue(null),TemplateContainer(typeof(SampleSpecificFormDataContainer),ComponentModel.BindingDirection.TwoWay),PersistenceMode(PersistenceMode.InnerProperty)]publicvirtualIBindableTemplateFormTemplate{get{returnformTemplate;}设置{formTemplate=value;}}#endregion公共覆盖ControlColle动作控制{get{EnsureChildControls();返回基地。控制;}}privateSampleSpecificFormDataContainerformDataContainer=null;[可浏览(假),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]publicSampleSpecificFormDataContainerFormDataContainer{get{EnsureChildControls();返回表单数据容器;}}[Bindable(true),Browsable(false)]publicSampleFormDataFormData{get{SampleFormDatadata=ViewState["FormData"]asSampleFormData;if(data==null){data=newSampleFormData();ViewState["FormData"]=数据;}返回数据;}}protectedoverridevoidCreateChildControls(){if(!this.ChildControlsCreated){this.ChildControlsCreated=true;控件.清除();formDataContainer=newSampleSpecificFormDataContainer(this);控件。添加(formDataContainer);FormTemplate.InstantiateIn(formDataContainer);}}protectedoverridevoidPerformDataBinding(Collections.IEnumerableignore){CreateChildControls();if(Page.IsPostBack){//OrderedDictionary字段=newOrderedDictionary();//ExtractValuesFromBindableControls(fields,formDataContainer);//不知道foreach是什么(System.Collections.DictionaryEntryentryinformTemplate.ExtractValues(formDataContainer)){if(((string)entry.Key).Equals("SampleString",StringComparison.Ordinal)){FormData.SampleString=(string)entry.Value;}if(((string)entry.Key).Equals("SampleInt",StringComparison.Ordinal)){inti;if(int.TryParse((string)entry.Value,outi)){FormData.SampleInt=i;}}}}formDataContainer.DataBind();}publicSampleSpecificEntryForm(){this.PreRender+=newEventHandler(SampleSpecificEntryForm_PreRender);}voidSampleSpecificEntryForm_PreRender(objectsender,EventArgse){SaveViewState();}#regionIDataSource成员publiceventEventHandlerDataSourceChanged;publicDataSourceViewGetView(stringviewName){returnnewPropertyView(this,viewName);}publicCollections.ICollectionGetViewNames(){returnnewList(){"SampleString","SampleInt","Items"};}#endregion}//尚未使用...publicclassPropertyView:DataSourceView{SampleSpecificEntryFormowner;字符串视图名称;protectedoverrideCollections.IEnumerableExecuteSelect(DataSourceSelectArgumentsarguments){if(viewName.Equals("SampleString",StringComparison.Ordinal)){返回新对象[]{owner.FormData.SampleString};}if(viewName.Equals("SampleInt",StringComparison.Ordinal)){returnnewobject[]{owner.FormData.SampleInt};}if(viewName.Equals("Items",StringComparison.Ordinal)){returnnewobject[]{owner.FormData.Items};}抛出新的InvalidOperationException();}publicPropertyView(SampleSpecificEntryFormowner,stringviewName):base(owner,viewName){this.owner=owner;this.viewName=viewName;}}}使用ASP.NET页面如下:欢迎使用ASP.NET!
