<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      TagSL框架設(shè)計(jì)(1)----先來點(diǎn)簡(jiǎn)介

      開篇

             最近在做一個(gè)Silverlight的框架。 

             噢,這是一個(gè)僅僅工作一年半的沒學(xué)歷的我做的!!

             現(xiàn)在還在開發(fā)中.....     因最近領(lǐng)導(dǎo)要看。我想先寫一篇簡(jiǎn)單的文章來介紹我的這種TagSL編程。

             事先聲明,這種編程與傳統(tǒng)的編程模式格格不入。不用ORM,不寫實(shí)體類,設(shè)計(jì)模式貌似沒有,甚至?xí)赬AML里寫Sql語句哦,并且強(qiáng)制要求沒特殊情況不能動(dòng)服務(wù)端的代碼啊!并且沒用WCF等高深技術(shù)啊!甚至于你會(huì)發(fā)現(xiàn)怎么我還提倡XAML文件用中文命名!.............  如果你是自認(rèn)為‘大?!牟⑶蚁矚g亂噴的人,請(qǐng)繞道,寒舍承受不了您大駕光臨。當(dāng)然,如果你有一定的編程經(jīng)驗(yàn),并愿意以平等的交流技術(shù)和建議的口吻來溝通,小弟感激不盡。因?yàn)檎胬碓睫q越明的。當(dāng)然也非常歡迎你提一些問題。我發(fā)誓會(huì)一一解答。

             噢,這篇文章是一篇介紹性的文章,又或者你可以理解為我52天后要開源的框架的預(yù)告版。所以不是‘附帶源代碼實(shí)例’的。請(qǐng)見諒呵呵。

       

      大綱

                 1、TagSL的核心目標(biāo)

          2、把那些那么多的XAML放到服務(wù)端去。

                 3、那兩個(gè)牛逼的查詢對(duì)象樹的方法。

                 4、不寫實(shí)體類了?

                 5、一個(gè)表單開始....

                 6、怎么獲得表單的值?

                 7、這樣弄有啥好處?

                 8、約定大于配置??

      1、TagSL的核心目標(biāo)

             根據(jù)《TagSL配置文檔》(還在書寫中哈哈),將常見業(yè)務(wù)交給每個(gè)控件都有的Tag屬性(用JSON字符安文檔串描述業(yè)務(wù)),不常見的業(yè)務(wù)交給代碼后置。

             (TagSL即Siverlight標(biāo)簽編程法,又或者叫Silverlight半配置編程法)

      2、把那些那么多的XAML放到服務(wù)端去。

             在有大型的Silverlight項(xiàng)目的時(shí)候,礙于天朝的網(wǎng)速,我們常常郁悶的問題就是項(xiàng)目越大,我們要使用的XAML文件越多。而XAML文件是一次打包到客戶端的。這樣導(dǎo)致XAML過大。并且如果一個(gè)項(xiàng)目有100個(gè)XAML文件。當(dāng)你修改了其中的一個(gè),要發(fā)布,也要將整個(gè)項(xiàng)目編譯一次才能看到效果。真麻煩??!

            我的TagSL做的第一件事就是就將XAML放到服務(wù)端。放到某個(gè)特定的目錄下。在做實(shí)際項(xiàng)目開發(fā)的時(shí)候,每個(gè)單獨(dú)的界面都實(shí)時(shí)從服務(wù)端下載(包括樣式文件),下載到客戶端之后使用 XamlReader.Load方法形成對(duì)橡樹。

            或許你會(huì)問,那代碼CS的文件呢?

            我會(huì)寫一個(gè)方法,唯一的參數(shù),參數(shù)就是這個(gè)XAML文件形成的對(duì)橡樹,并在對(duì)橡樹形成之后執(zhí)行這個(gè)方法。...... 然后就OK 了。這樣會(huì)有兩個(gè)問題,1是這樣會(huì)不會(huì)比傳統(tǒng)的CS文件做代碼后置有些功能不能實(shí)現(xiàn)?

            我的答案是是:如果你真正了解Silverlight,你會(huì)知道代碼CS文件能做到的,我的這種機(jī)制也能做到。因?yàn)閷?duì)橡樹的根傳過來了。我就能很輕易的操作這個(gè)對(duì)橡樹。而且因?yàn)槲业?span style="background-color: rgba(255, 255, 153, 1); color: rgba(153, 51, 102, 1)">TagSL編程在編碼過程中,要常常對(duì)XAML文件進(jìn)行更改,反之用C#代碼操縱對(duì)橡樹的方面不多(初步估計(jì)在8.5:1的樣子)。故在這樣的模式下,采用將XAML放在服務(wù)端是更好的。

       

      3、那幾個(gè)牛逼的查詢對(duì)象樹的方法。

             這個(gè)兩個(gè)方法我想不一定要在我的TagSL編程中。在其他的編程中同樣可以用到。

             查找對(duì)橡樹可以查孩子和父輩。而要知道Silvlight對(duì)橡樹分為邏輯對(duì)橡樹和可視化對(duì)橡樹(至于其區(qū)別請(qǐng)自行百度,個(gè)人認(rèn)為這兩個(gè)概念灰常重要)。

            在HTML里我們最喜歡Jqurey了,呵呵動(dòng)不動(dòng)就是$()   這樣去查找一個(gè)或者一些DOM元素。而在Silverlight里這樣的方法也是非常重要的。呵呵。

             這兩個(gè)方法在我這個(gè)框架中用的非常的多,而我相信他對(duì)你的編碼也會(huì)有幫助,當(dāng)然這是初始版本的,注釋啥的都不全,若可以請(qǐng)等待一個(gè)月后的開源版本呵呵。

            包含的方法主要有??梢暬瘜?duì)橡樹和邏輯對(duì)橡樹的  查詢孩子和父輩元素的方法。特別注意過濾條件的寫法噢 ....  呵呵

      View Code
       #region 可視化對(duì)象樹查詢方式--孩子

      public static List<T> Inspect<T>(DependencyObject dpObj, Func<T, bool> filter) where T : class
      {
      List<T> objList = new List<T>();
      if (filter == null)
      filter = _T => {
      return true;
      };
      Inspect<T>(0, dpObj, ref objList, filter);
      return objList;
      }

      private static void Inspect<T>(int level, DependencyObject dpObj, ref List<T> list, Func<T, bool> filter) where T : class
      {
      if ((dpObj is T))
      {
      if (filter(dpObj as T))
      list.Add(dpObj as T);
      }
      for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dpObj); i++)
      {
      Inspect<T>(level + 1, VisualTreeHelper.GetChild(dpObj, i), ref list, filter);
      }
      }

      #endregion

      #region 對(duì)象樹查詢方式--孩子

      /// <summary>
      /// 查詢孩子,用邏輯對(duì)象樹
      /// </summary>
      /// <param name="Prent">根對(duì)象</param>
      /// <param name="filter">過濾條件</param>
      /// <param name="list">返回對(duì)象集合</param>
      public static void getAllChild(DependencyObject Prent, Func<FrameworkElement, bool> filter, ref List<FrameworkElement> list)
      {
      if (((Prent is FrameworkElement)) && filter(Prent as FrameworkElement))
      {
      list.Add(Prent as FrameworkElement);
      }


      if (Prent is UserControl)
      {
      UserControl _contentControl = Prent as UserControl;
      if (_contentControl.Content is DependencyObject)
      getAllChild(_contentControl.Content as DependencyObject, filter, ref list);
      }
      if (Prent is ContentControl)
      {
      ContentControl _contentControl = Prent as ContentControl;
      if (_contentControl.Content is DependencyObject)
      getAllChild(_contentControl.Content as DependencyObject, filter, ref list);
      }
      if (Prent is Panel)
      {
      Panel p = Prent as Panel;
      foreach (UIElement item in p.Children)
      {
      if (item is DependencyObject)
      getAllChild(item as DependencyObject, filter, ref list);
      }
      }
      if (Prent is ItemsControl)
      {
      ItemsControl p = Prent as ItemsControl;
      foreach (var item in p.Items)
      {
      if (item is DependencyObject)
      getAllChild(item as DependencyObject, filter, ref list);
      }
      }

      }

      public static List<T> getAllChild<T>(DependencyObject Prent, Func<T, bool> filter) where T : class
      {
      List<T> list_T = new List<T>();
      if (filter == null)
      filter = _frameworkElement => {
      return true;
      };
      getAllChild<T>(Prent, filter, ref list_T);
      return list_T;
      }

      public static void getAllChild<T>(DependencyObject Prent, Func<T, bool> filter, ref List<T> list) where T : class
      {
      if (((Prent is T)) && filter(Prent as T))
      {
      list.Add(Prent as T);
      }


      if (Prent is UserControl)
      {
      UserControl _contentControl = Prent as UserControl;
      if (_contentControl.Content is DependencyObject)
      getAllChild(_contentControl.Content as DependencyObject, filter, ref list);
      }
      if (Prent is ContentControl)
      {
      ContentControl _contentControl = Prent as ContentControl;
      if (_contentControl.Content is DependencyObject)
      getAllChild(_contentControl.Content as DependencyObject, filter, ref list);
      }
      if (Prent is Panel)
      {
      Panel p = Prent as Panel;
      foreach (UIElement item in p.Children)
      {
      if (item is DependencyObject)
      getAllChild(item as DependencyObject, filter, ref list);
      }
      }
      if (Prent is ItemsControl)
      {
      ItemsControl p = Prent as ItemsControl;
      foreach (var item in p.Items)
      {
      if (item is DependencyObject)
      getAllChild(item as DependencyObject, filter, ref list);
      }
      }

      }


      #endregion

      #region 查詢祖輩
      public static void getAncestor(DependencyObject dobj, Func<FrameworkElement, bool> filter, ref List<FrameworkElement> _ancestor)
      {
      if ((dobj is FrameworkElement))
      {
      FrameworkElement parent = dobj as FrameworkElement;
      if (filter(parent))
      _ancestor.Add(parent);
      if (parent.Parent is FrameworkElement)
      {
      getAncestor(parent.Parent as FrameworkElement, filter, ref _ancestor);
      }
      }
      }
      public static void getAncestor<T>(DependencyObject dobj, Func<T, bool> filter, ref List<T> _ancestor) where T : FrameworkElement
      {
      T parent = dobj as T;
      if (filter == null)
      filter = _T =>
      {
      return true;
      };
      if (dobj is T && filter(parent))
      _ancestor.Add(parent);
      if (dobj is FrameworkElement)
      {
      getAncestor<T>((dobj as FrameworkElement).Parent, filter, ref _ancestor);
      }
      }
      public static List<T> getAncestor<T>(DependencyObject dobj, Func<T, bool> filter) where T : FrameworkElement
      {
      List<T> _ancestor = new List<T>();
      getAncestor<T>(dobj, filter, ref _ancestor);
      return _ancestor;
      }


      #endregion

       

      4、不寫實(shí)體類了?

            關(guān)于要不要實(shí)體類,實(shí)體類到底帶來了什么,我想我會(huì)再開博文呵呵。不過在這里要確定的一點(diǎn)是,在Silverlight里,不寫實(shí)體類是可以的,但實(shí)體類不能沒有!

           因?yàn)镾ilerlight最重要的一點(diǎn)就是數(shù)據(jù)綁定。而這里數(shù)據(jù)源就一定需要是對(duì)象。而這里的對(duì)象大部分就是我們從數(shù)據(jù)庫中取出來的數(shù)據(jù)并放到實(shí)體類中的單個(gè)對(duì)象或者對(duì)象集合。

           但是不寫實(shí)體類,怎么來‘對(duì)象呢’?-----反射!

          

      View Code
          #region 形成實(shí)體類
      public static List<String> GetCoumsByJson(string Json)
      {
      List<String> str_list = new List<string>();

      try
      {

      JsonValue ja = JsonArray.Parse(Json);
      foreach (string item in (((JsonObject)(ja[0]))).Keys)
      {
      if (!str_list.Contains(item))
      str_list.Add(item.ToUpper());
      }
      }
      catch (Exception e)
      {
      DealWithExpception(e, "根據(jù)Json獲得要生成的實(shí)體類的列名的集合的時(shí)候出錯(cuò)了,JSON內(nèi)容為" + Json);
      }

      return str_list;
      }


      public static Type getTypeByStrList(List<String> str_list)
      {


      string classInfo = "";
      str_list.ForEach((s) => {
      classInfo += s;
      });

      if (TagSlUserControl._AllTypes.ContainsKey(classInfo))
      {
      return TagSlUserControl._AllTypes[classInfo];
      }

      string className = "TempType" + Guid.NewGuid().ToString().Replace('-', 'a');
      try
      {
      #region 反射形成類型的初始工作
      AssemblyName an = new AssemblyName("TempAssembly" + Guid.NewGuid());
      AssemblyBuilder assemblyBuilder =
      AppDomain.CurrentDomain.DefineDynamicAssembly(
      an, AssemblyBuilderAccess.Run);
      ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
      TypeBuilder typeBuilder = moduleBuilder.DefineType(className
      , TypeAttributes.Public |
      TypeAttributes.Class |
      TypeAttributes.AutoClass |
      TypeAttributes.AnsiClass |
      TypeAttributes.BeforeFieldInit |
      TypeAttributes.AutoLayout
      , typeof(object));
      ConstructorBuilder constructor =
      typeBuilder.DefineDefaultConstructor(
      MethodAttributes.Public |
      MethodAttributes.SpecialName |
      MethodAttributes.RTSpecialName);
      #endregion

      #region 給類型加字段


      foreach (string item in str_list)
      {
      Type type = typeof(string);
      FieldBuilder fieldABuilder = typeBuilder.DefineField(item, type, FieldAttributes.Private);
      fieldABuilder.SetConstant("");
      PropertyBuilder propertyABuilder = typeBuilder.DefineProperty(item, System.Reflection.PropertyAttributes.None, type, null);
      MethodBuilder getPropertyABuilder = typeBuilder.DefineMethod("get",
      MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
      type,
      Type.EmptyTypes);

      ILGenerator getAIL = getPropertyABuilder.GetILGenerator();
      getAIL.Emit(OpCodes.Ldarg_0);
      getAIL.Emit(OpCodes.Ldfld, fieldABuilder);
      getAIL.Emit(OpCodes.Ret);
      //定義屬性A的set方法
      MethodBuilder setPropertyABuilder = typeBuilder.DefineMethod("set",
      MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
      null,
      new Type[] { type });
      //生成屬性A的set方法的IL代碼,即設(shè)置私有字段_a值為傳入的參數(shù)1的值
      ILGenerator setAIL = setPropertyABuilder.GetILGenerator();
      setAIL.Emit(OpCodes.Ldarg_0);
      setAIL.Emit(OpCodes.Ldarg_1);
      setAIL.Emit(OpCodes.Stfld, fieldABuilder);
      setAIL.Emit(OpCodes.Ret);
      //設(shè)置屬性A的get和set方法
      propertyABuilder.SetGetMethod(getPropertyABuilder);
      propertyABuilder.SetSetMethod(setPropertyABuilder);

      }
      #endregion

      TagSlUserControl._AllTypes.Add(classInfo, typeBuilder.CreateType());
      return TagSlUserControl._AllTypes[classInfo];
      }
      catch (Exception e)
      {
      string msg = "";
      foreach (string item in str_list)
      {
      msg += item + ";";
      }
      DealWithExpception(e, "根據(jù)字段生成實(shí)體的時(shí)候錯(cuò)了,getTypeByStrList(),字段內(nèi)容為" + msg);
      return "".GetType();
      }
      }


      #endregion

       =

         如我的代碼,其中有兩個(gè)方法。第一個(gè)是根據(jù)JSON數(shù)據(jù)形成一個(gè)List<String> 的集合,然后根據(jù)這個(gè)集合的‘字段’,遍歷形成一個(gè)實(shí)體類。當(dāng)然在這個(gè)時(shí)候必須要關(guān)注的是,反射會(huì)影響性能嗎?

      我的回答是,不會(huì)!為什么呢?因?yàn)槲业姆瓷錂C(jī)制.....  呵呵 Emit不是蓋的!

         當(dāng)然需要注意的是,這里的JSON數(shù)據(jù)是根據(jù)DataTable形成的。

         而接下來我們只需要采取反序列化的方式,即可將數(shù)據(jù)放到這個(gè)實(shí)體里或者實(shí)體集合里。然后寫一個(gè) _panel.DataContext=實(shí)體或者實(shí)體集合...  即可。

      5、舉例說明一個(gè)‘表單’的配置

               如果你看到了這。我可以明確的告訴你,上面四點(diǎn)。其實(shí)就是我的TagSL編程的最核心的東西 呵呵。 如果說我這個(gè)框架用到了什么‘高深’的技術(shù)的話,上面幾點(diǎn)算是最高深的了呵呵。

               下面直入主題。我們來配置一個(gè)簡(jiǎn)單的表單配置

               下面就是我的界面的樣子 呵呵。

               

         

         而配置XAML如下

        

      View Code
      <UserControl
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x
      ="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d
      ="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc
      ="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable
      ="d" Tag=" {PKValue:'9A1D8CC2-8789-5B1C-ABB7-334C94F9FA51'} "
      xmlns:Intersoft
      ="http://intersoft.clientui.com/schemas"
      xmlns:Converters
      ="clr-namespace:Contacts_MVVM.Converters"
      xmlns:System
      ="clr-namespace:System;assembly=mscorlib"
      xmlns:design
      ="clr-namespace:Contacts_MVVM.ViewModels"
      x:Class
      ="MyXaml.UserControl1" FontFamily="Arial,SimSun"
      d:DesignWidth
      ="640" d:DesignHeight="480">
      <UserControl.Resources>
      <Style x:Key="TextBoxStyle" TargetType="Intersoft:UXTextBox">
      <Setter Property="Margin" Value="10,0,0,0"/>
      <Setter Property="Height" Value="26.2"></Setter>
      </Style>
      <Style x:Key="FieldLabelStyle" TargetType="Intersoft:StylishLabel">
      <Setter Property="Width" Value="80"/>
      <Setter Property="HorizontalContentAlignment" Value="Right"/>
      <Setter Property="Padding" Value="4,0"/>
      <Setter Property="FontSize" Value="14"/>
      <Setter Property="Background" Value="{x:Null}"/>
      <Setter Property="BorderBrush" Value="{x:Null}"/>
      <Setter Property="Foreground" Value="#FF6F6D6D"/>
      </Style>
      <Style x:Key="FormStyle" TargetType="StackPanel">
      <Setter Property="Orientation" Value="Horizontal"/>
      <Setter Property="Margin" Value="0,2"/>
      <Setter Property="MinHeight" Value="20"/>
      </Style>
      </UserControl.Resources>

      <Grid>
      <Grid Background="White" Tag=" {TableName: 'Test-Student', 'ControlType': 1} ">
      <Intersoft:ExpandableGroupBox FontSize="14" Header="學(xué)生【基本信息】">
      <Grid>
      <Grid.RowDefinitions>
      <RowDefinition Height="42"/>
      <RowDefinition Height="42"/>
      <RowDefinition Height="42"/>
      <RowDefinition Height="*"/>
      </Grid.RowDefinitions>
      <Grid.ColumnDefinitions>
      <ColumnDefinition Width="0.33*"/>
      <ColumnDefinition Width="0.33*"/>
      </Grid.ColumnDefinitions>
      <StackPanel Style="{StaticResource FormStyle}" Orientation="Horizontal" Grid.Row="0" Grid.Column="0">
      <Intersoft:StylishLabel Style="{StaticResource FieldLabelStyle}" Content="姓名:" />
      <Intersoft:UXTextBox Style="{StaticResource TextBoxStyle}" Width="180" Tag=" {ActField:'StudentName'} "/>
      </StackPanel>
      <StackPanel Style="{StaticResource FormStyle}" Orientation="Horizontal" Grid.Row="1" Grid.Column="0">
      <Intersoft:StylishLabel Style="{StaticResource FieldLabelStyle}" Content="郵箱:" />
      <Intersoft:UXTextBox Style="{StaticResource TextBoxStyle}" Width="180" Tag=" {ActField:'Email',RegEx:'\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*'} "/>
      </StackPanel>
      <StackPanel Style="{StaticResource FormStyle}" Orientation="Horizontal" Grid.Row="1" Grid.Column="1">
      <Intersoft:StylishLabel Style="{StaticResource FieldLabelStyle}" Content="移動(dòng)電話:" />
      <Intersoft:UXTextBox Style="{StaticResource TextBoxStyle}" Width="180" Tag=" {ActField:'Call'} "/>
      </StackPanel>
      <StackPanel Style="{StaticResource FormStyle}" Orientation="Horizontal" Grid.Row="0" Grid.Column="1" >
      <Intersoft:StylishLabel Style="{StaticResource FieldLabelStyle}" Content="生日:" />
      <Intersoft:UXDateTimePicker Margin="10,10,0,0" Width="180" Tag=" {ActField:'Birthday'} "/>
      </StackPanel>
      <StackPanel Style="{StaticResource FormStyle}" Orientation="Horizontal" Grid.Row="2" Grid.Column="1">
      <Intersoft:StylishLabel Style="{StaticResource FieldLabelStyle}" Content="班級(jí):" />
      <Intersoft:UXComboBox Height="22" Margin="10,0,0,0" Width="180" Tag=" {ActField:'ClassID',ShowField:'[Test-Class].ClassName'} ">

      </Intersoft:UXComboBox>
      </StackPanel>
      <StackPanel Style="{StaticResource FormStyle}" Orientation="Horizontal" Grid.Row="2" Grid.Column="0">
      <Intersoft:StylishLabel Style="{StaticResource FieldLabelStyle}" Content="年級(jí):" />
      <Intersoft:UXComboBox Height="22" Tag=" {ShowField:'[Test-Grade].GradeName',CascadeSql:'
      SELECT dbo.[Test-Class].ClassName, dbo.[Test-Grade].GradeName
      FROM dbo.[Test-Class] INNER JOIN dbo.[Test-Grade] ON dbo.[Test-Class].GradeID = dbo.[Test-Grade].GradeID'
      } "

      Margin
      ="10,0,0,0" Width="180">

      </Intersoft:UXComboBox>
      </StackPanel>
      </Grid>


      </Intersoft:ExpandableGroupBox>

      <Intersoft:UXCommandBar Height="44" VerticalAlignment="Bottom" Grid.Row="1" FontSize="12">

      <Intersoft:UXButton x:Name="btnSave" Tag=" {BtnType:'Save'} " Content="保存" Width="80" IsDefault="True"
      DialogResult
      ="None"/>
      <Intersoft:UXButton x:Name="bbbbbbbbbbbbbbbbbbbbbbbbbbb" Content="取消" Width="80" IsCancel="True"/>

      </Intersoft:UXCommandBar>
      </Grid>
      </Grid>
      </UserControl>

       

       

       首先我確定的一件事是,表單元素的容器一定是一個(gè)Pannl。(幾乎一定是Grid,呵呵)。

       

       我們會(huì)在這個(gè)Pannl上配置(注意這里的配置即Tag的值

      {TableName: 'Test-Student',  'ControlType': 1}

       這樣的話,我的控件初始化器(其實(shí)就是幾個(gè)方法)就會(huì)找到這個(gè)Pannel并根據(jù)ControlType為1 知道這是一個(gè)表單的容器。并知道這個(gè)表單對(duì)應(yīng)的表是Test-Student這個(gè)表。

       接下來每個(gè)字段都回有相應(yīng)的配置。你會(huì)注意到幾乎都有{:''}   這個(gè)配置。這個(gè)配置我的用意就是告訴表單初始化器這個(gè)表單擁有的這個(gè)字段。還有日期字段。日期字段我的控件初始化器會(huì)自動(dòng)識(shí)別其為日期字段,并做響應(yīng)的轉(zhuǎn)換。當(dāng)然你會(huì)注意到還有下拉列表框。注意如果這個(gè)下拉列表框的值是由另一個(gè)表的話。配置的方法是這樣   ShowField:'[Test-Class].ClassName'    。即‘[表名].字段名’的方式。  這樣這個(gè)下拉列表框就會(huì)自動(dòng)的填充值。呵呵。

       特別要注意以下幾點(diǎn)

      A:我的服務(wù)端會(huì)根據(jù)表名自動(dòng)的知道每個(gè)表單的表的主鍵是哪一個(gè)。甚至我會(huì)根據(jù)表的字段信息查詢這個(gè)字段的非空屬性等等。

      B:還有一些功能比如每個(gè)字段還可以加入正則表達(dá)式驗(yàn)證等等。而這些只需要在XAML的控件的Tag里加一個(gè)簡(jiǎn)單的配置而已呵呵。

      C:而且如果你自信你會(huì)發(fā)現(xiàn)UserControl里有這么一個(gè)配置 Tag=" {PKValue:'9A1D8CC2-8789-5B1C-ABB7-334C94F9FA51'} "。呵呵,這個(gè)PKValue就是指當(dāng)前這個(gè)UserControl------這個(gè)樣的UserContrl我稱之為  Page,即一個(gè)界面。這個(gè)PKValue就是我定義的一個(gè)界面級(jí)別的值。  注意上圖我的那個(gè) 表單里頭的值就是通過這個(gè)主鍵找到的。當(dāng)然這么長的一個(gè)主鍵是不需要你配置呵呵。比如當(dāng)我們?cè)谝粋€(gè)列表當(dāng)中點(diǎn)擊某一條數(shù)據(jù)編輯的時(shí)候,我們的做法要將UserControl的Tag屬性賦值。就象我們?cè)贖TML的列表里點(diǎn)擊某條數(shù)據(jù)編輯一條記錄彈出一個(gè)窗口我們要URL傳值過去一樣呵呵》。。。。。     舉這例子只為說明Tag在我的框架里除了作為配置之外。另外一個(gè)重要的用途就是‘界面?zhèn)鬟f值’ 呵呵。

      D:我會(huì)根據(jù)ActField這個(gè)配置自動(dòng)的生成一個(gè)綁定器,當(dāng)然是雙向綁定。

      6、怎么獲得‘表單’的值呢?

              string data = JsonConvert.SerializeObject(_panel.DataContext);

             這里的data就是我們要獲得的表單的所有的值,JsonConvert是一NewTonSoft里的一個(gè)類。SerializeObject是反序列化。_panel就是我們的那個(gè)表單。

             呵呵,沒錯(cuò)。我們這樣就獲得了表單當(dāng)中的值。呵呵。

       

      7、這樣弄有啥好處呢?

             A: 加快了編程速度。傳統(tǒng)咱們要弄一個(gè)‘表單’啥的要前后折騰半天。而且那啥下拉列表框的級(jí)聯(lián)等等也要搞半天.....   在我這你只需要兩個(gè)配置即可。呵呵而且不只表單哦。。。。  列表,樹,ListBox......。都能用這個(gè)配置直接配置出來噢.....

            B:讓代碼更加統(tǒng)一了。其實(shí)以前我們的開發(fā)。比較蛋疼的事情就是如果 十個(gè)人實(shí)現(xiàn)同一個(gè)功能,往往寫出來的代碼會(huì)有十個(gè)模樣(即便是團(tuán)隊(duì)有著非常詳細(xì)的編碼文檔,代碼也可能五花八門)。當(dāng)我們做代碼交接的時(shí)候往往要將代碼解釋半天。而用這樣的配置,則會(huì)讓代碼風(fēng)格非常統(tǒng)一。

            C:牛逼的培訓(xùn)。呵呵,正式版本發(fā)布的時(shí)候,一定是伴隨這非常詳細(xì)的文檔,實(shí)例例子,甚至視頻教學(xué)噢。我想一個(gè)框架給力不給力其實(shí)很重要的一部分就是學(xué)習(xí)資料爽不爽。我想這一點(diǎn)因?yàn)楦绲拇嬖诓粫?huì)差  哈哈。

       

       

      8、約定大于配置?

             這話我想你聽過。。。。呵呵。編程大牛常常說這話。那么按照這個(gè)字面意思理解,是不是我的編程方式不如‘約定編程’呢。

             錯(cuò)。呵呵,要知道這話你是不能只理解面的意思的。

            約定大于配置本意就是要約束開發(fā)人員按照某約定的模式編程,盡量把更多的東西約定好統(tǒng)一好,而不是‘配置’(此配置非彼配置)。

           那么我的這種編碼模式剛好符合這種理念。又或者我的編碼模式可以叫約定型編程。即約定了咱們就這么在Tag里寫那些來實(shí)現(xiàn)業(yè)務(wù)呵呵。

       

      未完待續(xù)

             呵呵,現(xiàn)在我的TagSL還在開發(fā)期,還有一些細(xì)節(jié)的一些東西需要優(yōu)化。我曾說過要在52天后放出一個(gè)開源版本。呵呵。我明年可能還會(huì)將工作流啥的集成進(jìn)來噢.... 哈哈。

        

            誠然,我想我一定會(huì)遭到一部分兄弟的噴擊。畢竟我才入行一年,就居然說要做框架。怎么這么狂妄呵呵(一個(gè)哥們對(duì)我說的原話)......     其實(shí)我只是想尋找更優(yōu)秀的軟件制作方式而已。唉....

            噢,忘了說了,雖然我只編程了一年半,但要注意的是我的框架是站在居然的肩膀上...   呵呵。

            為什么我會(huì)如此執(zhí)著的弄著一個(gè)‘框架’?為什么我一個(gè)才兩年不到編程的人敢于弄框架?為什么我對(duì)‘配置’如此.....    請(qǐng)看下集 《我在hangar學(xué)配置》

            談的是在一個(gè)幾乎天天談配置的公司的學(xué)習(xí)經(jīng)歷。

            這家公司有不懂編程語言的人憑配置做了兩年開發(fā)了..  你信嗎??

       

      posted @ 2011-12-11 22:10  銀光小子  閱讀(3376)  評(píng)論(19)    收藏  舉報(bào)
      主站蜘蛛池模板: 美女自卫慰黄网站| 内射极品少妇xxxxxhd| 国产无遮挡裸体免费久久| 汉阴县| 国产精品午夜福利导航导| 日韩有码av中文字幕| 中文字幕人妻无码一夲道| ww污污污网站在线看com| 99久久国产成人免费网站| 中文字幕一区日韩精品| 国产精品亚洲二区在线播放| 神农架林区| 成人一区二区三区在线午夜| 漂亮人妻中文字幕丝袜| 色窝窝免费播放视频在线| 日本大片在线看黄a∨免费| 亚洲国产精品久久久久婷婷图片| 色综合色狠狠天天综合网| 日本黄漫动漫在线观看视频| 性色欲情网站iwww九文堂| 天天影视色香欲综合久久| 亚洲AV永久无码天堂网一线| 国产精一品亚洲二区在线播放| 好吊妞| 亚洲精品日韩在线观看| 无码天堂va亚洲va在线va| 国产精品成人亚洲一区二区| 国内精品久久人妻无码不卡| 重口SM一区二区三区视频| 亚洲综合欧美在线…| 国产精品毛片一区视频播| 国产99久久亚洲综合精品西瓜tv | 久久久精品国产精品久久| 先锋影音男人av资源| 精品国产乱码一区二区三区| 国产99精品成人午夜在线| 40岁大乳的熟妇在线观看| 中文字幕无码免费久久99| 丁香五月网久久综合| 久久久亚洲欧洲日产国码αv| 午夜福利精品一区二区三区 |