⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 accordion.cs

📁 AJAX 应用 实现页面的无刷新
💻 CS
📖 第 1 页 / 共 3 页
字号:
        /// and hooks up the appropriate event listener for the
        /// DataSourceViewChanged event. The return value is the new view (if
        /// any) that was connected to. An exception is thrown if there is
        /// a problem finding the requested view or data source.
        /// </summary>
        /// <returns>New View</returns>
        [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", Justification = "Assembly is not localized")]
        private DataSourceView ConnectToDataSourceView()
        {
            // If the current view is correct, there is no need to reconnect
            if (_currentViewValid && !DesignMode)
                return _currentView;

            // Disconnect from old view, if necessary
            if ((_currentView != null) && (_currentViewIsFromDataSourceID))
            {
                // We only care about this event if we are bound through the DataSourceID property
                _currentView.DataSourceViewChanged -= new EventHandler(OnDataSourceViewChanged);
            }

            // Connect to new view
            IDataSource ds = null;
            string dataSourceID = DataSourceID;

            if (!string.IsNullOrEmpty(dataSourceID))
            {
                // Try to find a DataSource control with the ID specified in DataSourceID
                Control control = NamingContainer.FindControl(dataSourceID);
                if (control == null)
                    throw new HttpException(String.Format(CultureInfo.CurrentCulture, "DataSource '{1}' for control '{0}' doesn't exist", ID, dataSourceID));
                ds = control as IDataSource;
                if (ds == null)
                    throw new HttpException(String.Format(CultureInfo.CurrentCulture, "'{1}' is not a data source for control '{0}'.", ID, dataSourceID));
            }

            if (ds == null)
            {
                // DataSource control was not found, construct a temporary data source to wrap the data
                return null;
            }
            else
            {
                // Ensure that both DataSourceID as well as DataSource are not set at the same time
                if (DataSource != null)
                    throw new InvalidOperationException("DataSourceID and DataSource can't be set at the same time.");
            }

            // IDataSource was found, extract the appropriate view and return it
            DataSourceView newView = ds.GetView(DataMember);
            if (newView == null)
                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, "DataSourceView not found for control '{0}'", ID));

            _currentViewIsFromDataSourceID = IsBoundUsingDataSourceID;
            _currentView = newView;
            // If we're bound through the DataSourceID proeprty, then we care about this event
            if ((_currentView != null) && (_currentViewIsFromDataSourceID))
                _currentView.DataSourceViewChanged += new EventHandler(OnDataSourceViewChanged);
            _currentViewValid = true;

            return _currentView;
        }

        /// <summary>
        /// Bind the Accordion to its DataSource
        /// </summary>
        public override void DataBind()
        {
            // Don't databind to a data source control when the control is in the designer but not top-level
            if (IsBoundUsingDataSourceID && DesignMode && (Site == null))
                return;

            // do our own databinding
            RequiresDataBinding = false;
            OnDataBinding(EventArgs.Empty);
        }

        /// <summary>
        /// DataBind the Accordion to its panes
        /// </summary>
        /// <param name="e">EventArgs</param>
        protected override void OnDataBinding(EventArgs e)
        {
            base.OnDataBinding(e);

            //Only bind if the control has the DataSource or DataSourceID set
            if (this.DataSource!=null || IsBoundUsingDataSourceID)
            {
                // reset the control state
                ClearPanes();
                ClearChildViewState();

                // and then create the control hierarchy using the datasource
                CreateControlHierarchy(true);
                ChildControlsCreated = true;
            }
        }

        /// <summary>
        /// Create the new control hierarchy of AccordionPanes
        /// (using the DataSource if specificed)
        /// </summary>
        /// <param name="useDataSource">Whether or not we should use the DataSource</param>
        protected virtual void CreateControlHierarchy(bool useDataSource)
        {
            int count = -1;
            IEnumerable dataSource = null;
            List<AccordionPane> itemsArray = new List<AccordionPane>();

            if (!useDataSource)
            {
                object viewCount = ViewState[ItemCountViewStateKey];

                // ViewState must have a non-null value for ItemCount because we check for
                // this in CreateChildControls
                if (viewCount != null)
                {
                    count = (int)viewCount;
                    if (count != -1)
                    {
                        List<object> dummyList = new List<object>(count);
                        for (int i = 0; i < count; i++)
                            dummyList.Add(null);
                        dataSource = dummyList;
                        itemsArray.Capacity = count;
                    }
                }
            }
            else
            {
                dataSource = GetData();
                count = 0;
                ICollection collection = dataSource as ICollection;
                if (collection != null)
                    itemsArray.Capacity = collection.Count;
            }

            if (dataSource != null)
            {
                int index = 0;
                foreach (object dataItem in dataSource)
                {
                    AccordionPane ap = new AccordionPane();
                    Controls.Add(ap);

                    CreateItem(dataItem, index, AccordionItemType.Header, ap.HeaderContainer, HeaderTemplate, useDataSource);
                    CreateItem(dataItem, index, AccordionItemType.Content, ap.ContentContainer, ContentTemplate, useDataSource);

                    itemsArray.Add(ap);

                    count++;
                    index++;
                }
            }

            // If we're binding, save the number of items contained in the repeater for use in round-trips
            if (useDataSource)
                ViewState[ItemCountViewStateKey] = ((dataSource != null) ? count : -1);
        }

        /// <summary>
        /// Create an AccordionPane's item (either Header or Content) and raise the ItemCreated event
        /// </summary>
        /// <param name="dataItem">Item's data</param>
        /// <param name="index">Index</param>
        /// <param name="itemType">Type of the item (Header or Content)</param>
        /// <param name="container">Control to fill</param>
        /// <param name="template">Template for the binding</param>
        /// <param name="dataBind">Whether or not to bind</param>
        private void CreateItem(object dataItem, int index, AccordionItemType itemType, AccordionContentPanel container, ITemplate template, bool dataBind)
        {

            if (template == null)
                return;

            AccordionItemEventArgs itemArgs = new AccordionItemEventArgs(container, itemType);
            OnItemCreated(itemArgs);

            container.SetDataItemProperties(dataItem, index, itemType);
            template.InstantiateIn(container);

            if (dataBind)
            {
                container.DataBind();
                OnItemDataBound(itemArgs);
            }
        }

        /// <summary>
        /// Ensure that the Accordion has been databound if it needed to be
        /// </summary>
        protected void EnsureDataBound()
        {
            try
            {
                _throwOnDataPropertyChange = true;
                if (RequiresDataBinding && !string.IsNullOrEmpty(DataSourceID))
                    DataBind();
            }
            finally
            {
                _throwOnDataPropertyChange = false;
            }
        }

        /// <summary>
        /// Returns an IEnumerable that is the DataSource, which either came
        /// from the DataSource property or from the control bound via the
        /// DataSourceID property.
        /// </summary>
        /// <returns>DataSource</returns>
        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Performs complex action")]
        protected virtual IEnumerable GetData()
        {
            _selectResult = null;
            DataSourceView view = ConnectToDataSourceView();
            if (view != null)
            {
                Debug.Assert(_currentViewValid);

                // create a handle here to make sure this is a synchronous operation.
                _selectWait = new EventWaitHandle(false, EventResetMode.AutoReset);
                view.Select(SelectArguments, new DataSourceViewSelectCallback(DoSelect));
                _selectWait.WaitOne();

            }
            else if (DataSource != null)
            {
                _selectResult = DataSource as IEnumerable;
            }
            return _selectResult;
        }

        /// <summary>
        /// Create the DataSourceSelectArguments (which just defaults to the Empty value
        /// because we don't want to sort, filter, etc.)
        /// </summary>
        /// <returns>DataSourceSelectArguments</returns>
        protected virtual DataSourceSelectArguments CreateDataSourceSelectArguments()
        {
            return DataSourceSelectArguments.Empty;
        }

        /// <summary>
        /// Select the data
        /// </summary>
        /// <param name="data">Data</param>
        private void DoSelect(IEnumerable data)
        {
            _selectResult = data;
            _selectWait.Set();
        }

        /// <summary>
        /// Wrap the CommandArgs of an ItemCommand event with AccordionCommandEventArgs
        /// </summary>
        /// <param name="source">Source</param>
        /// <param name="args">EventArgs</param>
        /// <returns>Whether the event was handled</returns>
        protected override bool OnBubbleEvent(object source, EventArgs args)
        {
            bool handled = false;
            AccordionCommandEventArgs accordionArgs = args as AccordionCommandEventArgs;
            if (accordionArgs != null)
            {
                OnItemCommand(accordionArgs);
                handled = true;
            }
            return handled;
        }

        /// <summary>
        /// This method is called when DataMember, DataSource, or DataSourceID is changed.
        /// </summary>
        [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", Justification = "Assembly is not localized")]
        protected virtual void OnDataPropertyChanged()
        {
            if (_throwOnDataPropertyChange)
                throw new HttpException("Invalid data property change");
            if (_initialized)
                RequiresDataBinding = true;
            _currentViewValid = false;
        }

        /// <summary>
        /// Indicate that we need to be databound whenever the DataSourceView changes
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="args">EventArgs</param>
        protected virtual void OnDataSourceViewChanged(object sender, EventArgs args)
        {
            RequiresDataBinding = true;
        }

        /// <summary>
        /// Raise the ItemCommand event
        /// </summary>
        /// <param name="args">EventArgs</param>
        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Using appropriate EventArgs for the Event")]
        protected virtual void OnItemCommand(AccordionCommandEventArgs args)
        {
            if (ItemCommand != null)
                ItemCommand(this, args);
        }

        /// <summary>
        /// Raise the ItemCreatedEvent
        /// </summary>
        /// <param name="args">EventArgs</param>
        protected virtual void OnItemCreated(AccordionItemEventArgs args)
        {
            if (ItemCreated != null)
                ItemCreated(this, args);
        }

        /// <summary>
        /// Raise the ItemDataBound event
        /// </summary>
        /// <param name="args">EventArgs</param>
        protected virtual void OnItemDataBound(AccordionItemEventArgs args)
        {
            if (ItemDataBound != null)
                ItemDataBound(this, args);
        }

#endregion
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -