动态数据源的绑定

来源:互联网 发布:硕鼠 youtube mac 编辑:程序博客网 时间:2024/06/05 23:51

动态数据源的绑定

  • 提供一种思路,可以简易地对动态数据做页面展示与绑定
  • 以XML的形式构建控件,便于直观地控制结构
  • 方便UI加装
  • 便于对动态数据做表单验证

场景1:页面上的控件个数或是属性不固定,需要由数据库中的数据去决定

基本步骤:
- 1. 构建XML文本
- 2. 使用XmlTextReader生成控件
- 3. 将控件放入页面

window.cs

StackPanel sp;//容器List<SourceModel> sourceList = GetSource();//数据源//构建文本框集合string xmlControls;foreach (sourceModel in sourceList){    xmlControls = xmlControls +        "<c1:C1MaskedTextBox Text=\"" + sourceModel.Content + "\"/>";}//构建StackPanel,将文本框集合放入其中string strXaml = "<StackPanel " + "xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" " +   "xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" " +   "xmlns:c1=\"http://schemas.componentone.com/winfx/2006/xaml\" " +   "xmlns:basicControls=\"clr-namespace:ShenLianSystem.Common.BasicControls\" " +   "Orientation=\"Horizontal\" " +   ">" +"<StackPanel.Resources>" +   "<ResourceDictionary>" +   "<ResourceDictionary.MergedDictionaries>" +   "<ResourceDictionary Source=\"/Resources/Skins/Global.xaml\"></ResourceDictionary>" +   "</ResourceDictionary.MergedDictionaries>" +   "</ResourceDictionary>" +   "</StackPanel.Resources>" +   xmlControls +"</StackPanel>";//根据构建好的XML,生成控件childrenStringReader strreader = new StringReader(strXaml);System.Xml.XmlTextReader xmlreader = new System.Xml.XmlTextReader(strreader);var children = XamlReader.Load(xmlreader) as FrameworkElement;//生成的内容//将控件children放入容器spsp.Children.Clear();sp.Children.Add(children);

场景2:在场景1的基础上,需要对数据源中的数据做update操作

一般情况下需要做绑定属性:

window.cs

xmlControls = "<c1:C1MaskedTextBox Text=\"{Binding sourceModel1.Content , Mode=TwoWay}\"/>" +                "<c1:C1MaskedTextBox Text=\"{Binding sourceModel2.Content, Mode=TwoWay}\"/>" +                "<c1:C1MaskedTextBox Text=\"{Binding sourceModel3.Content, Mode=TwoWay}\"/>" +                ...;

viewmodel

SourceModel sourceModel1 { get; set; }SourceModel sourceModel2 { get; set; }SourceModel sourceModel3 { get; set; }...

**但由于属性个数不确定,无法在后台声明对应的变量
用一个动态类型包装一下,将这些数目不确定的变量变成这个动态实体的属性**

window.cs

for(int i = 1; i <= sourceList.Count; i++){    xmlControls = xmlControls +         "<c1:C1MaskedTextBox Text=\"{Binding dynamicSourceModel.sourceModel" + i + ".Content, Mode=TwoWay}\"/>";}

viewmodel

DynamicSourceModel dynamicSourceModel{ get; set; }/// <summary>/// 构建动态实体/// </summary>public void SetModel(){    for(int i = 1; i <= sourceList.Count; i++){        dynamicSourceModel.TrySetMember("sourceModel" + i , sourceList[i]);    }}/// <summary>/// 动态实体类/// </summary>public class DynamicSourceModel : DynamicObject{    Dictionary<string, SourceModel> Properties = new Dictionary<string, SourceModel>();    /// <summary>    /// 赋值    /// </summary>    /// <param name="key">变量名</param>    /// <param name="value">变量值</param>    public void TrySetMember(string key, SourceModel value)    {        Properties[key] = value;    }    /// <summary>    /// 取值    /// </summary>    /// <param name="key">变量名</param>    /// <param name="result">是否有此变量</param>    /// <returns>变量值</returns>    public bool TryGetMember(string key, out SourceModel result)    {        return Properties.TryGetValue(key, out result);    }    /// <summary>    /// 按约束重写    /// </summary>    /// <param name="binder"></param>    /// <param name="result"></param>    /// <returns></returns>    public override bool TryGetMember(GetMemberBinder binder, out object result)    {        bool TryGetResult;        SourceModel model;        TryGetResult = Properties.TryGetValue(binder.Name, out model);        result = model;        return TryGetResult;    }    /// <summary>    /// 取值    /// </summary>    /// <returns>变量字典</returns>    public Dictionary<string, SourceModel> TryGetMember()    {        return Properties;    }}
0 0