in

ASPXWizard.net

.net and Ajax Community

Mina Labib

November 2009 - Posts

  • Enable JQuery Intellisense in Visual Studio 2008

    I was expecting that Visual studio will do the magic for me and enable Intellisense for JQuery javascript library automatically once I add the library and referenced it in my page – naive, right?- anyways it did not happen of course, so with a quick look to the internet and beloved Scott Guthrie blog I found that I need couple of steps to enable it; It is easy and quick steps so I liked to share it with other naive developers :).

    1. Install Visual Studio 2008 SP1.
      This service pack adds richer javascript intellisense support for Visual Studio 2008, you will find it here.
    2. Install Visual Studio 2008 Patch KB958502 to support “-vsdoc.js” Intellisense files
      This patch apply for VS2008 SP1 and VWD Express SP1, enables Visual Studio to detect “-vsdoc.js” files when javascript library is referenced and use it to enable Javascript Intellisense. This patch can be found here.
    3. Download the JQeury Visual Studio doc file.
      You can find this file with ASP.NET MVC package as it is included by default or you can find it in JQuery official web site as Visual Studio documentation.VS08 JQuery
    4. Save “vsdoc.js” file in the same directory
      Save the Visual Studio documentation file in the same directory of the JQuery library, and then you can reference the library in your page as below:
      <script src="../../Scripts/jquery-1.3.2.js" type="text/javascript"></script>
      start now to use the Javascript Intellisense feature.
      Important Trick:
      Sometimes we use partial views or user controls in our project and we do not to refer to Javascript library within it, we usually refer to it in Master page or the parent page; Visual Studio has no way to know this script is available in for the user control or the partial view, thus Javascript Intellisense will NOT be enabled in these files, to enable Javascript Intellisense in the partial/user control there is a useful trick by reference the library surrounded with If(false) statement which will never be rendered in the run time, but still provide Javascript intellisense in the design time.
      <% if (false)
         { %>
         <script src="../../Scripts/jquery-1.3.2.js" type="text/javascript"></script>
      <% } %>


    References:



  • Adding web reference in class library – ASP.NET MVC

     

    It is change in .NET 3.5 using ASP.NET MVC you can’t find ‘Add Web Reference’ option in right click context menu inside a class library (if you do not have web references in your class library).

    But I found how to add .NET 2.0 based web reference through adding Service Reference, I quoted the following sentence from a forum thread.

    As for the "Add Service Reference", it is used for creating client proxy of WCF service(it will generate a client proxy class). Also, since WCF include webservice communication ability, you can use it to create  client proxy for webservice too.

     

    Below are steps I used to add web reference to a web service in class library in my ASP.NET MVC solution.

    1. Right click ‘References’ folder under class library project (there is no Add Web Reference option) instead select ‘Add Service Refrence’
      1
    2. In Add Service Reference window click Advanced… button
      2
    3. in Service Reference Setting Window click Add Web Reference button
      3
    4. Now you are landing on regular .NET 2.0 Add Web Reference window and you can provide a web service URL to be added to your class library.

    by adding web reference and from now on you can see ‘Add Web Reference’ option in the right click context menu of Reference folder

    4

     

     

     

     

    and also Visual studio will create a Web References folder underneath your class library.



  • Generic editable GridView - ASP.NET MVC

    The goal is to build editable data grid in a project uses ASP.NET MVC 1.0, it is know that ASP.NET MVC does not use controls with ( runat=”server” ) attribute, which means I can’t use regular DataGrid or GridView in my code. and HTMLHelper class in ASP.NET MVC does provide such HTML component.

    So, there are two solutions:

    1. Using extension to extend HTMLHelper functionality and build HTML using code
         1: public static class GridViewExt
         2:     {
         3:         public static string GridView(this HtmlHelper html, IEnumerable DataSource, object HTMLAtrributes)
         4:         {
         5:             string htmlAttributesString = ConvertToAtrributes.ConvertObjectToAttributeList(HTMLAtrributes).Trim();
         6:             StringBuilder resultBuilder = new StringBuilder();
         7:             resultBuilder.AppendFormat("<table{0}{1}>", string.IsNullOrEmpty(htmlAttributesString) ? "" : " ", htmlAttributesString).AppendLine();
         8:             IEnumerator sourceEnumerator = DataSource.GetEnumerator();
         9:             Type itemType;
        10:             if (sourceEnumerator.MoveNext() == false)
        11:             {
        12:                 return "";
        13:             }
        14:             else
        15:             {
        16:                 itemType = sourceEnumerator.Current.GetType();
        17:             }
        18:             PropertyInfo[] properties = itemType.GetProperties();
        19:             resultBuilder.AppendLine("\t<tr>");
        20:             foreach (PropertyInfo property in properties)
        21:             {
        22:                 resultBuilder.AppendFormat("\t\t<th>{0}</th>", property.Name).AppendLine();
        23:             }
        24:             resultBuilder.AppendLine("\t</tr>");
        25:             foreach (object item in DataSource)
        26:             {
        27:                 resultBuilder.AppendLine("\t<tr>");
        28:                 foreach (PropertyInfo property in properties)
        29:                 {
        30:                     resultBuilder.AppendFormat("\t\t<td>{0}</td>", property.GetValue(item, null)).AppendLine();
        31:                 }
        32:                 resultBuilder.AppendLine("\t</tr>");
        33:             }
        34:             resultBuilder.Append("</table>");
        35:             return resultBuilder.ToString();
        36:         }
        37:     }
        38: public class ConvertToAtrributes
        39:     {
        40:         public static string ConvertObjectToAttributeList(object value)
        41:         {
        42:             StringBuilder builder = new StringBuilder();
        43:             if (value != null)
        44:             {
        45:                 IDictionary<string, object> dictionary = value as IDictionary<string, object>;
        46:                 if (dictionary == null)
        47:                 {
        48:                     dictionary = new RouteValueDictionary(value);
        49:                 }
        50:                 string format = "{0}=\"{1}\" ";
        51:                 foreach (string str2 in dictionary.Keys)
        52:                 {
        53:                     object obj2 = dictionary[str2];
        54:                     if (dictionary[str2] is bool)
        55:                     {
        56:                         obj2 = dictionary[str2].ToString().ToLowerInvariant();
        57:                     }
        58:                     builder.AppendFormat(format, str2.Replace("_", "").ToLowerInvariant(), obj2);
        59:                 }
        60:             }
        61:             return builder.ToString();
        62:         }
        63:     }
             now you should be able to call to call HTMLHelper extended method inside your View
        1: <%= this.Html.GridView(Model.Products)%>
      but it is still not editable and to add editing functionality it will be so hard to write a lot of HTML code inside C# code and will not be easy to maintain or fix issues; so let’s consider the second option.
    2. Building User control and get advantage of writing HTML inside the user control HTML (one thing to remember using ASP.NET MVC no use for page life cycle you can get rid of that).
      Now let me build a user control ascx page using fantastic JQuery fetures 
         1: <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="GridView.ascx.cs" Inherits="Shared.UserControls.GridView" %>
         2: <%@ Import Namespace="System.Reflection" %>
         3: <%
         1: -- style code --
      %>
         4: <style type="text/css">
         5:     .gridView
         6:     {
         7:         border-collapse: collapse;
         8:     }
         9:     .gridView th, .gridView td
        10:     {
        11:         padding: 5px;
        12:     }
        13:     .gridView th
        14:     {
        15:         border-bottom: double 3px black;
        16:     }
        17:     .gridView td
        18:     {
        19:         border-bottom: solid 1px black;
        20:     }
        21:     .alternatingItem
        22:     {
        23:         background-color: lightgrey;
        24:     }
        25: </style>
        26: <%
         1: -- Javascripts code --
      %>
        27: <script src="../../Scripts/jquery-1.3.2.js" type="text/javascript"></script>
         1:  
         2: <%--<script src="../../Scripts/jquery-1.3.2-vsdoc.js" type="text/javascript">
         1: </script>--%>
         2: <script type="text/javascript">
         3:     var controller = '';
         4:     var SaveAction = '';
         5:     <% GetController(); GetSaveAction(); %>
         6:     function IsValidAction(ctrl, actn)
         7:     {
         8:         if(($.trim(ctrl) == '') || ($.trim(actn) == ''))
         9:             return false;
        10:         else
        11:             return true;
        12:     }
        13:     function SaveAllClick() {
        14:         //debugger;
        15:         if(!IsValidAction(controller,SaveAction))
        16:         {
        17:             alert("Error while saving data");
        18:             return;
        19:         }
        20:         var i = 0;
        21:         var inputs = new Array();
        22:         $("#BaseTable").find("input").each(function() {
        23:             inputsIdea = [this.id, this.value];
        24:             i++;
        25:         });
        26:  
        27:         var columnsCount = $("#BaseTable").find("th").length;
        28:         $.post("/"+controller+"/"+SaveAction, { inputs: inputs, columnsCount: columnsCount });
        29:         Border();
        30:         $("#ChangeFlag").text("");
        31:         $("#SaveAll").attr("disabled", "disabled");
        32:         alert("Saved");
        33:     }
        34:     var prevCell;
        35:     function Border(cell) {
        36:         if (prevCell != null) {
        37:             $(prevCell).attr("style", "border-style: none");
        38:         }
        39:         if (cell != null) {
        40:             var i = $(cell); //.find("input");
        41:             i.attr("style", "border-style: inset");
        42:         }
        43:         prevCell = cell;
        44:     }
        45:     function Unborder(cell) {
        46:         if (cell != null) {
        47:             var i = $(cell); //.find("input");
        48:             i.attr("style", "border-style: none");
        49:         }
        50:     }
        51:     function MarkChanges() {
        52:         $("#ChangeFlag").text("Page should be saved");
        53:         $("#SaveAll").removeAttr("disabled");
        54:     }
      </script>
        28: <%
         1: -- Show the Headers --
      %>
        29: <table class="gridView" id="BaseTable">
        30:     <thead>
        31:         <tr>
        32:             <%
         1:  foreach (PropertyInfo prop in this.Columns)
         2:                { 
      %>
        33:             <th>
        34:                 <%
         1: = prop.Name 
      %>
        35:             </th>
        36:             <%
         1:  } 
      %>
        37:         </tr>
        38:     </thead>
        39:     <%
         1: -- Show the Rows --
      %>
        40:     <tbody>
        41:         <%
         1:  foreach (object row in this.Rows)
         2:            { 
      %>
        42:         <tr class="<%= this.FlipCssClass( "item", "alternatingItem") %>">
        43:             <%
         1: -- Show Each Column --
      %>
        44:             <%
         1:  foreach (PropertyInfo prop in this.Columns)
         2:                { 
      %>
        45:             <td>
        46:                 <%
         1:  var typeCode = Type.GetTypeCode(prop.PropertyType); 
      %>
        47:                 <%
         1: var str_disabled = "";
         2:                   if (this.GetAtt(prop.Name))
         3:                       str_disabled = "disabled=\"disabled\"";
         4:                  
      %>
        48:                 <%
         1: -- String Columns --
      %>
        49:                 <%
         1:  if (typeCode == TypeCode.String)
         2:                    { 
      %>
        50:                 <input id="<%=prop.Name %>" type="text" style="border-style: none" value="<%= GetColumnValue(row, prop.Name)%>"
        51:                     onmousedown="Border(this)" onselect="Border(this)" onblur="Unborder(this)" onchange="MarkChanges()"
        52:                     &lt;%= str_disabled %&gt; />
        53:                 <%
         1:  } 
      %>
        54:                 <%
         1: -- DateTime Columns --
      %>
        55:                 <%
         1:  if (typeCode == TypeCode.DateTime)
         2:                    { 
      %>
        56:                 <input id="<%=prop.Name %>" type="text" style="border-style: none" value="<%= GetColumnValue(row, prop.Name, "{0:D}")%>"
        57:                     onmousedown="Border(this)" onselect="Border(this)" onblur="Unborder(this)" onchange="MarkChanges()"
        58:                     &lt;%= str_disabled %&gt; />
        59:                 <%
         1:  } 
      %>
        60:                 <%
         1: -- Decimal Columns --
      %>
        61:                 <%
         1:  if (typeCode == TypeCode.Decimal)
         2:                    { 
      %>
        62:                 <input id="<%=prop.Name %>" type="text" style="border-style: none" value="<%= GetColumnValue(row, prop.Name, "{0:f}") %>"
        63:                     onmousedown="Border(this)" onselect="Border(this)" onblur="Unborder(this)" onchange="MarkChanges()"
        64:                     &lt;%= str_disabled %&gt; />
        65:                 <%
         1:  } 
      %>
        66:                 <%
         1: -- Decimal Columns --
      %>
        67:                 <%
         1:  if (typeCode == TypeCode.Double)
         2:                    { 
      %>$
        68:                 <input id="<%=prop.Name %>" type="text" style="border-style: none" value="<%= GetColumnValue(row, prop.Name, "{0:f}") %>"
        69:                     onmousedown="Border(this)" onselect="Border(this)" onblur="Unborder(this)" onchange="MarkChanges()"
        70:                     &lt;%= str_disabled %&gt; />
        71:                 <%
         1:  } 
      %>
        72:                 <%
         1: -- Boolean Columns --
      %>
        73:                 <%
         1:  if (typeCode == TypeCode.Boolean)
         2:                    { 
      %>
        74:                 <%
         1:  if ((bool)(this.GetColumnValue(row, prop.Name)))
         2:                    { 
      %>
        75:                 <input type="checkbox" disabled="disabled" checked="checked" />
        76:                 <%
         1:  }
         2:                    else
         3:                    { 
      %>
        77:                 <input type="checkbox" disabled="disabled" />
        78:                 <%
         1:  } 
      %>
        79:                 <%
         1:  } 
      %>
        80:                 <%
         1: -- Integer Columns --
      %>
        81:                 <%
         1:  if (typeCode == TypeCode.Int32)
         2:                    { 
      %>
        82:                 <input id="<%=prop.Name %>" type="text" style="border-style: none" value="<%= GetColumnValue(row, prop.Name)%>"
        83:                     onmousedown="Border(this)" onselect="Border(this)" onblur="Unborder(this)" onchange="MarkChanges()"
        84:                     &lt;%= str_disabled %&gt; />
        85:                 <%
         1:  } 
      %>
        86:             </td>
        87:             <%
         1:  } 
      %>
        88:         </tr>
        89:         <%
         1:  } 
      %>
        90:     </tbody>
        91: </table>
        92: <p>
        93:     <input id="SaveAll" disabled="disabled" type="button" value="Save" onclick="SaveAllClick()" />
        94:     <span id="ChangeFlag"></span>
        95: </p>
      and building code behind code for this user control using last post idea of TypeDescriptor class to make the user control more generic accepting any type of collection and render editable properties according to custom attributes associated with it.
         1: using System;
         2: using System.Collections;
         3: using System.Collections.Generic;
         4: using System.Linq;
         5: using System.Web;
         6: using System.Web.UI;
         7: using System.Web.Mvc;
         8: using System.Reflection;
         9: using System.ComponentModel;
        10: using CustomAtrributes;
        11:  
        12: namespace Shared.UserControls
        13: {
        14:     public partial class GridView : System.Web.Mvc.ViewUserControl<IEnumerable>
        15:     {
        16:         protected string GetController()
        17:         {
        18:             
        19:             if (ViewContext.RouteData.Values["Controller"] != null)
        20:             {
        21:                 Response.Write("controller = '" + ViewContext.RouteData.Values["Controller"] as string + "';");
        22:                 return ViewContext.RouteData.Values["Controller"] as string;
        23:             }
        24:             else
        25:                 return string.Empty;
        26:         }
        27:         protected string GetSaveAction()
        28:         {
        29:             if (ViewData.Model.GetType().GetProperty("SaveAction") != null)
        30:             {
        31:                 Response.Write("SaveAction = '" + DataBinder.Eval(ViewData.Model, "SaveAction") as string + "';");
        32:                 return DataBinder.Eval(ViewData.Model, "SaveAction") as string;
        33:             }
        34:             else
        35:                 return string.Empty;
        36:         }
        37:         protected PropertyInfo[] Columns
        38:         {
        39:             
        40:             get 
        41:             {
        42:                 var e = ViewData.Model.GetEnumerator();
        43:                 e.MoveNext();
        44:                 object firstRow = e.Current;
        45:                 if (firstRow == null)
        46:                 {
        47:                     throw new Exception("No data passed to GridView User Control.");
        48:                 }
        49:                 return firstRow.GetType().GetProperties();
        50:             }
        51:         }
        52:         protected IEnumerable Rows
        53:         {
        54:             get { return ViewData.Model; }
        55:         }
        56:         protected object GetColumnValue(object row, string columnName)
        57:         {
        58:             return DataBinder.Eval(row, columnName);
        59:         }
        60:         protected object GetColumnValue(object row, string columnName, string format)
        61:         {
        62:             return DataBinder.Eval(row, columnName, format); 
        63:         }
        64:         bool flip = false;
        65:         protected string FlipCssClass(string className, string alternativeClassName)
        66:         {
        67:             flip = !flip;
        68:             return flip ? className : alternativeClassName;
        69:         }
        70:         
        71:         protected bool GetAtt(string Name)
        72:         {
        73:             
        74:             bool readonlyatt = false;
        75:             UIAttributes uiatt = TypeDescriptor.GetAttributes(Model).Cast<Attribute>().SingleOrDefault(a => a.GetType().Name == typeof(UIAttributes).Name) as UIAttributes;
        76:             if ((uiatt != null) && uiatt.IsReadOnly)
        77:                 return uiatt.IsReadOnly;
        78:             PropertyInfo propInfo = Model.GetType().GetProperty(Name);
        79:                 //(propInfo =>
        80:                     {
        81:                         PropertyDescriptor propDescriptor = TypeDescriptor.GetProperties(Model).Cast<PropertyDescriptor>().SingleOrDefault(p => propInfo.Name == p.Name);
        82:                         if (propDescriptor != null)
        83:                         {
        84:                             UIAttributes attrib = propDescriptor.Attributes.Cast<Attribute>().SingleOrDefault(p => p.GetType().Name == typeof(UIAttributes).Name) as UIAttributes;
        85:                             if (attrib != null)
        86:                             {
        87:                                 readonlyatt = attrib.IsReadOnly;
        88:                             }
        89:                         }
        90:                     }
        91:                     //);
        92:                     return readonlyatt;
        93:         }
        94:     }
        95: }
      and by using couple of ASP.NET MVC helpful classes like ViewContext, now I can detect which controller called this user control automatically and by adding new property to the the ViewData specifaying the Save Action method name in the controller; that gives more generic to the user control as it is not tight to specific controller or  methods.

    Still need more enhancements and features like validation and styles, but so far it is nice.

    It was very nice challenge to build such a control and I owe to references I mention below a lot.

    References:



  • Run time (Dynamic) attributes in C#

    In the current project I was concerned to build generic user control, accept generic collection and paint collection elements details in HTML table and allow editing functionality for specific columns. The challenge is to detect the editable properties in the collection elements in the run time without knowing the collection or columns types.

    My idea was to decorate desired properties with custom Attributes to specify the layout behavior; Attributes can be accessed and obtained using Reflection in the run time, the idea seems working fine.

    So, what are attributes in c#?

    "Attributes provide a powerful method of associating declarative information with C# code (types, methods, properties, and so forth). Once associated with a program entity, the attribute can be queried at run time and used in any number of way" - MSDN.

    Also attributes are classes that inherits System.Attribute as below

    [AttributeUsage(AttributeTargets.Property)]

    public class UIAttributes : Attribute

    {

    private bool isReadOnly = false;

    public bool IsReadOnly

    {

    get { return isReadOnly; }

    }

    public UIAttributes(bool isReadOnly)

    {

    this.IsReadOnly = isReadOnly;

    }

    }

    Then decorate class property with the custom attribute:

    public class ProductViewData

    {

    public string Name { get; set; }

    [UIAttributes(true)] //ProdcutID property is decorated to be read only.

    public int ProductID { get; set; }

    public double Price { get; set; }

    }

    Then by using reflection we can detect which property has the custom attribute and paint attribute according to that.

    public void DetectProperties(object o)

    {

    PropertyInfo[] propInfo = o.GetType().GetProperties();

    foreach(PropertyInfo prop in propInfo)

    {

    foreach(Attribute att in prop.GetCustomAttributes(true))

    {

    if((att is UIAttributes) && (((UIAttributes)att).IsReadOnly) )

    {

    //Do somthing.

    }

    }

    }

    }

    But let's say the same property should be editable in a view and non-editable in other view, then property behavior should be changed at run time to toggle between the editable/read-only mode, and custom attributes does now allow to be changed at runtime.

    So, after some readings there was no easy way to do that, but there was a great class in System.ComponentModel namespace called TypeDescriptor which allow dynamically assigning and querying metadata on instance on runtime, it seems like it is our solution.

    The only drawback is the long way to implement it, so first I built Interface representing any type need to follow my custom attribute:

    Interface:

    public interface IUIAttributes

    {

    bool IsReadOnly(string PName);

    bool IsReadOnly();

    }

    Custom Attribute:

    [AttributeUsage(AttributeTargets.Property)]

    public class UIAttributes : Attribute

    {

    private bool isReadOnly = false;

    public bool IsReadOnly

    {

    get { return isReadOnly; }

    set { isReadOnly = value; }

    }

    public UIAttributes()

    {

    }

    public UIAttributes(bool isReadOnly)

    {

    this.IsReadOnly = isReadOnly;

    }

    }

    Any Class implements the interface:

    public class ProductViewData : IUIAttributes

    {

    public string Name { get; set; }

    public int ProductID { get; set; }

    public double Price { get; set; }

    #region IUIAttributes Members

    bool IUIAttributes.IsReadOnly(string PName)

    {

    if (PName.Equals("ProductID"))

    return true;

    else

    return false;

    }

    bool IUIAttributes.IsReadOnly()

    {

    return false;

    }

    #endregion

    }

    Now I have to write a CustomTypeDescriptor and Provider, this descriptor will create instances of my custom attribute UIAttribute and associate them to types that implement the Interface:

    public sealed class CustomTypeDescriptionProvider : TypeDescriptionProvider where T : IUIAttributes

    {

    ///

    /// Constructor

    ///

    public CustomTypeDescriptionProvider(TypeDescriptionProvider parent)

    : base(parent)

    {

    }

    ///

    /// Create and return a custom type descriptor and chains it with the original

    /// custom type descriptor

    ///

    public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)

    {

    return new UIAttributeCustomTypeDescriptor(base.GetTypeDescriptor(objectType, instance));

    }

    }

    public sealed class UIAttributeCustomTypeDescriptor : CustomTypeDescriptor where T : IUIAttributes

    {

    ///

    /// Constructor

    ///

    public UIAttributeCustomTypeDescriptor(ICustomTypeDescriptor parent)

    : base(parent)

    {

    }

    public override AttributeCollection GetAttributes()

    {

    Type UIType = typeof(T).GetInterface(typeof(IUIAttributes).Name);

    if (UIType != null)

    {

    IUIAttributes UIInstance = GetPropertyOwner(base.GetProperties().Cast<PropertyDescriptor>().First()) as IUIAttributes;

    bool instanceLevelRoles = UIInstance.IsReadOnly();

    List<Attribute> attributes = new List<Attribute>(base.GetAttributes().Cast<Attribute>());

    UIAttributes UIAttrib = new UIAttributes(instanceLevelRoles);

    TypeDescriptor.AddAttributes(UIInstance, UIAttrib);

    attributes.Add(UIAttrib);

    return new AttributeCollection(attributes.ToArray());

    }

    return base.GetAttributes();

    }

    ///

    /// This method add a new property to the original collection

    ///

    public override PropertyDescriptorCollection GetProperties()

    {

    // Enumerate the original set of properties and create our new set with it

    PropertyDescriptorCollection originalProperties = base.GetProperties();

    List<PropertyDescriptor> newProperties = new List<PropertyDescriptor>();

    Type UIType = typeof(T).GetInterface("IUIAttributes");

    if (UIType != null)

    {

    foreach (PropertyDescriptor pd in originalProperties)

    {

    IUIAttributes UIInstance = GetPropertyOwner(pd) as IUIAttributes;

    bool propertyIsReadOnly = UIInstance.IsReadOnly(pd.Name);

    UIAttributes UIAttrib = new UIAttributes(propertyIsReadOnly);

    // Create a new property and add it to the collection

    PropertyDescriptor newProperty = TypeDescriptor.CreateProperty(typeof(T), pd.Name, pd.PropertyType, UIAttrib);

    newProperties.Add(newProperty);

    }

    // Finally return the list

    return new PropertyDescriptorCollection(newProperties.ToArray(), true);

    }

    return base.GetProperties();

    }

    }

    I have overridden GetAttributes in which I query the underlying instance to get read-only mode of the instance. Similarly, I have also overridden GetProperties which will in turn query the instance to get read-only mode of the specified property name.

    We are now ready to associate the UIAttribute with our class instances.

    ProductViewData pvd = new ProductViewData();

    pvd.ProductID = 1;

    pvd.Name = "Product1";

    pvd.Price = 99.99;

    TypeDescriptor.AddProvider(new CustomTypeDescriptionProvider<ProductViewData>(TypeDescriptor.GetProvider(typeof(ProductViewData))),pvd);

    And then by Reflection we can get properties attributes and check its layout behavior without knowing instance type, in next piece of code ‘Model’ is the instance name and ‘Name’ is the property name.

    public bool IsPropReadOnly(string Name)

    {

    bool readonlyatt = false;

    UIAttributes uiatt = TypeDescriptor.GetAttributes(Model).Cast<Attribute>().SingleOrDefault(a => a.GetType().Name == typeof(UIAttributes).Name) as UIAttributes;

    if ((uiatt != null) && uiatt.IsReadOnly)

    return uiatt.IsReadOnly;

    PropertyInfo propInfo = Model.GetType().GetProperty(Name);

    //(propInfo =>

    {

    PropertyDescriptor propDescriptor = TypeDescriptor.GetProperties(Model).Cast<PropertyDescriptor>().SingleOrDefault(p => propInfo.Name == p.Name);

    if (propDescriptor != null)

    {

    UIAttributes attrib = propDescriptor.Attributes.Cast<Attribute>().SingleOrDefault(p => p.GetType().Name == typeof(UIAttributes).Name) as UIAttributes;

    if (attrib != null)

    {

    readonlyatt = attrib.IsReadOnly;

    }

    }

    }

    //);

    return readonlyatt;

    }

    Thanks for this Post it helps a lot.

ASPXWizard.net some rights reserved 2005-2007
Powered by Community Server (Non-Commercial Edition), by Telligent Systems