DataBindingPanel.cs :  » Inversion-of-Control-Dependency-Injection » Spring.net » Spring » Web » UI » Controls » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Inversion of Control Dependency Injection » Spring.net 
Spring.net » Spring » Web » UI » Controls » DataBindingPanel.cs
#region License

/*
 * Copyright 2002-2004 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#endregion

#region Imports

using System;
using System.ComponentModel;
using System.Reflection;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using Common.Logging;
using Spring.Core;
using Spring.Core.TypeResolution;
using Spring.DataBinding;
using Spring.Globalization;
using Spring.Objects;
using Spring.Util;
using AttributeCollectionSystem.Web.UI.AttributeCollection;
using BindingDirectionSpring.DataBinding.BindingDirection;

#endregion

namespace Spring.Web.UI.Controls{
    /// <summary>
    /// Any WebControl placed on a DataBindingPanel may be bound 
    /// to a model by adding an attribute "BindingTarget"
    /// </summary>
    /// <author>Erich Eichinger</author>
    [PersistChildren(true),
    ToolboxData("<{0}:DataBindingPanel runat=\"server\" Width=\"125px\" Height=\"50px\"> </{0}:DataBindingPanel>"), 
    ParseChildren(false),
#if NET_1_1
    Designer("System.Web.UI.Design.WebControls.PanelDesigner, System.Design, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), 
#else
    Designer("System.Web.UI.Design.WebControls.PanelContainerDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), 
#endif
    AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal), 
    AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    public class DataBindingPanel : Panel
    {
        private const string ATTR_BINDINGTARGET = "BindingTarget";
        private const string ATTR_BINDINGSOURCE = "BindingSource";
        private const string ATTR_BINDINGDIRECTION = "BindingDirection";
        private const string ATTR_BINDINGFORMATTER = "BindingFormatter";
        private const string ATTR_BINDINGTYPE = "BindingType";
        private const string ATTR_MESSAGEID = "MessageId";
        private const string ATTR_ERRORPROVIDERS = "ErrorProviders";

        private static readonly ILog Log = LogManager.GetLogger(typeof(DataBindingPanel));

        private delegate void TraversalAction(IWebDataBound bindingContainer, WebControl wc);

        /// <summary>
        /// Registers this control for the <see cref="UserControl.DataBindingsInitialized"/> event of it's container.
        /// </summary>
        protected override void OnInit(EventArgs e)
        {
            RegisterDataControl(this, new EventHandler(BindingOwner_DataBindingsInitialized));
            base.OnInit(e);
        }

        /// <summary>
        /// Overridden to remove custom binding attributes before rendering.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPreRender(EventArgs e)
        {
            // remove custom attributes
            if (this.HasControls())
            {
                this.TraverseControls(null, this.Controls, new TraversalAction(this.RemoveBindingAttributes));
            }

            base.OnPreRender(e);
        }

        /// <summary>
        /// Overriden to suppress rendering this control's tag
        /// </summary>
        /// <param name="writer"></param>
        protected override void Render(HtmlTextWriter writer)
        {
            base.RenderContents(writer);
        }

        /// <summary>
        /// Called by the containing <see cref="UserControl"/> if bindings must be initialized.
        /// </summary>
        private void BindingOwner_DataBindingsInitialized(object sender, EventArgs e)
        {
            IWebDataBound bindingContainer = (IWebDataBound) sender;
            if (this.HasControls())
            {
                this.TraverseControls(bindingContainer, this.Controls, new TraversalAction(this.BindControl));
            }
        }

        /// <summary>
        /// Adds all controls on this panel to the containing <see cref="UserControl.BindingManager"/>'s binding collection.
        /// </summary>
        /// <param name="bindingContainer">the usercontrol containing this panel</param>
        /// <param name="controls">the <see cref="ControlCollection"/> of controls to be bound</param>
        /// <param name="action">action to be performed on matching controls</param>
        private void TraverseControls(IWebDataBound bindingContainer, ControlCollection controls, TraversalAction action)
        {
            foreach (Control control in controls)
            {
                // DataBindingPanels must not be nested
                if (control is DataBindingPanel)
                {
                    throw new HttpException("Controls of type DataBindingPanel must not be nested");
                }

                // abort recursion on LiteralControl or nested UserControl
                if (control is LiteralControl
                    || control is UserControl)
                {
                    continue;
                }

                // if it's a WebControl, check for binding-related attributes
                WebControl wc = control as WebControl;
                if (wc != null)
                {
                    try
                    {
                        action(bindingContainer, wc);
                    }
                    catch (Exception ex)
                    {
                        string msg =
                            string.Format("Error executing action on control '{0}' of type '{1}'", wc.UniqueID,
                                          wc.GetType().FullName);
                        Log.Error(msg, ex);
                        throw new HttpException(msg, ex);
                    }
                }

                if (control.HasControls())
                {
                    this.TraverseControls(bindingContainer, control.Controls, action);
                }
            }
        }

        /// <summary>
        /// Retrieves custom binding attributes from a webcontrol and adds a new binding
        /// instance to the container's <see cref="UserControl.BindingManager"/> if necessary.
        /// </summary>
        private void BindControl(IWebDataBound dataBound, WebControl theControl)
        {
            // special handling of adapted controls
            DataBindingAdapter adapterControl = theControl as DataBindingAdapter;

            Control wc = (adapterControl != null && adapterControl.WrappedControl != null) ? adapterControl.WrappedControl : theControl;

            AttributeCollection attributeCollection = theControl.Attributes;
            string bindingTarget = attributeCollection[ATTR_BINDINGTARGET];

            // at least a BindingTarget must be specified
            if (bindingTarget == null)
            {
                return;
            }
            attributeCollection.Remove(ATTR_BINDINGTARGET);

            // determine direction
            BindingDirection bindingDirection = BindingDirection.Bidirectional;
            string strBindingDirection = attributeCollection[ATTR_BINDINGDIRECTION];
            if (strBindingDirection != null)
            {
                bindingDirection = (BindingDirection) Enum.Parse(typeof(BindingDirection), strBindingDirection);
            }

            // determine BindingSource
            string bindingSource = attributeCollection[ATTR_BINDINGSOURCE];
            if (bindingSource == null)
            {
                bindingSource = AutoProbeSourceProperty(wc);
            }
            attributeCollection.Remove(ATTR_BINDINGSOURCE);

            // get formatter if any
            IFormatter bindingFormatter = null;
            string bindingFormatterName = attributeCollection[ATTR_BINDINGFORMATTER];
            if (bindingFormatterName != null)
            {
                bindingFormatter = (IFormatter) dataBound.ApplicationContext.GetObject(bindingFormatterName);
                attributeCollection.Remove(ATTR_BINDINGFORMATTER);
            }

            // determine source expression
            string containerName = dataBound.UniqueID;
            string controlName = wc.UniqueID;
            string relativeControlName = null;
            if ( dataBound is System.Web.UI.Page )
            {
                relativeControlName = string.Format("FindControl('{0}')", controlName);
            }
            else if ( (Control)dataBound != this.NamingContainer)
            {
                relativeControlName = (controlName.StartsWith(containerName)) ? controlName.Substring(containerName.Length + 1) : controlName;
                relativeControlName = string.Format("FindControl('{0}')", relativeControlName);
            }
            else
            {
                relativeControlName = wc.ID;
            }
            // if no bindingSource, expression evaluates to the bound control
            bindingSource = (StringUtils.HasLength(bindingSource))
                                ? relativeControlName + "." + bindingSource
                                : relativeControlName;

            Log.Debug(
                string.Format("binding control '{0}' relative to '{1}' using expression '{2}'", controlName,
                              containerName, bindingSource));

            //get bindingType if any
            IBinding binding = null;
            string bindingTypeName = attributeCollection[ATTR_BINDINGTYPE];
            if (bindingTypeName == null)
            {
                bindingTypeName = AutoProbeBindingType(wc);
            }

            // get messageId and errorProviders list
            string messageId = attributeCollection[ATTR_MESSAGEID];
            string errorProvidersText = attributeCollection[ATTR_ERRORPROVIDERS];
            string[] errorProviders = null;
            if (StringUtils.HasLength(errorProvidersText))
            {
                errorProviders = (string[])new Spring.Core.TypeConversion.StringArrayConverter().ConvertFrom(errorProvidersText);
            }

            // add binding to BindingManager
            if (bindingTypeName != null)
            {
                binding = CreateBindingInstance(bindingTypeName, bindingSource, bindingTarget, bindingDirection, bindingFormatter);
                binding = dataBound.BindingManager.AddBinding(binding);
            }
            else
            {
                binding = dataBound.BindingManager.AddBinding(bindingSource, bindingTarget, bindingDirection, bindingFormatter);
            }

            // set error message
            if (StringUtils.HasLength(messageId))
            {
                binding.SetErrorMessage( messageId, errorProviders );
            }
        }

        /// <summary>
        /// Removes custom binding attributes from a webcontrol to avoid them being rendered.
        /// </summary>
        private void RemoveBindingAttributes(IWebDataBound dataBound, WebControl wc)
        {
            AttributeCollection attributeCollection = wc.Attributes;
            attributeCollection.Remove(ATTR_BINDINGTARGET);
            attributeCollection.Remove(ATTR_BINDINGSOURCE);
            attributeCollection.Remove(ATTR_BINDINGTYPE);
            attributeCollection.Remove(ATTR_BINDINGDIRECTION);
            attributeCollection.Remove(ATTR_BINDINGFORMATTER);
        }

        /// <summary>
        /// Probe for bindingType of know controls
        /// </summary>
        /// <param name="wc">the control, who's bindingType is to be determined</param>
        /// <returns>null, if standard binding is to be used or the fully qualified typename of the binding implementation</returns>
        protected virtual string AutoProbeBindingType(Control wc)
        {
            if (wc is ListBox && ((ListBox) wc).SelectionMode == ListSelectionMode.Multiple)
            {
                return typeof(MultipleSelectionListControlBinding).FullName;
            }
            return null;
        }

        /// <summary>
        /// Probes for a few know controls and their properties.
        /// </summary>
        /// <returns>
        /// The 'BindingSource' expression to be used for binding this control.
        /// </returns>
        protected virtual string AutoProbeSourceProperty(Control wc)
        {
            if (wc is ListBox && ((ListBox) wc).SelectionMode == ListSelectionMode.Multiple)
            {
                return null; // force evaluate to control itself
            }
            else if (wc is CheckBoxList)
            {
                return "SelectedValues";
            }
            else if (wc is ListControl)
            {
                return "SelectedValue";
            }
            else if (wc is CheckBox)
            {
                return "Checked";
            }
            else if (wc is TextBox)
            {
                return "Text";
            }
#if NET_2_0
            else if (wc is HiddenField)
            {
                return "Value";
            }
#endif
            else if (wc is RadioButtonGroup)
            {
                return "Value";
            }
            else if (wc is DataBindingAdapter)
            {
                throw new ArgumentNullException("Attribute 'BindingSource' is mandatory when using DataBindingAdapter");
            }

            throw new ArgumentNullException("Attribute 'BindingSource' is missing and control is of unknown type");
        }

        private static IBinding CreateBindingInstance(string bindingTypeName, string bindingSource, string bindingTarget, BindingDirection bindingDirection, IFormatter bindingFormatter)
        {
            IBinding binding;
            Type bindingType = TypeResolutionUtils.ResolveType(bindingTypeName);
            ConstructorInfo ctor =
                bindingType.GetConstructor(new Type[] {typeof(string), typeof(string), typeof(BindingDirection), typeof(IFormatter)});

            if (ctor == null)
            {
                throw new ArgumentException(string.Format("Specified BindingType '{0}' does not implement constructor (string,string,BindingDirection,IFormatter)",bindingTypeName));
            }
            binding =
                (IBinding)
                ObjectUtils.InstantiateType(ctor, new object[] {bindingSource, bindingTarget, bindingDirection, bindingFormatter});
            return binding;
        }

        private static void RegisterDataControl(Control control, EventHandler initializeBindingHandler)
        {
            GetBindingContainerControl(control).DataBindingsInitialized += initializeBindingHandler;
        }

        private static IWebDataBound GetBindingContainerControl(Control control)
        {
            Control parent = control;
            while (parent != null)
            {
                if (parent is IWebDataBound)
                {
                    return (IWebDataBound) parent;
                }
                parent = parent.Parent;
            }
            return null;
        }
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.