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

📄 virtualobjectlistview.cs

📁 Linux 恢复盘制作工具 process调用busybox dd实现写*.img镜像
💻 CS
📖 第 1 页 / 共 3 页
字号:
        /// <param name="modelObjects">Collection of objects to be removed</param>
        /// <remarks>
        /// <para>Nulls and model objects that are not in the ListView are silently ignored.</para>
        /// <para>Due to problems in the underlying ListView, if you remove all the objects from
        /// the control using this method and the list scroll vertically when you do so,
        /// then when you subsequenially add more objects to the control,
        /// the vertical scroll bar will become confused and the control will draw one or more
        /// blank lines at the top of the list. </para>
        /// </remarks>
        public override void RemoveObjects(ICollection modelObjects)
        {
            if (this.DataSource == null) 
                return;

            // Give the world a chance to cancel or change the removed objects
            ItemsRemovingEventArgs args = new ItemsRemovingEventArgs(modelObjects);
            this.OnItemsRemoving(args);
            if (args.Canceled)
                return;

            this.ClearCachedInfo();
            this.DataSource.RemoveObjects(args.ObjectsToRemove);
            this.UpdateVirtualListSize();
        }

        /// <summary>
        /// Select the row that is displaying the given model object. All other rows are deselected.
        /// </summary>
        /// <param name="setFocus">Should the object be focused as well?</param>
        public override void SelectObject(object modelObject, bool setFocus)
        {
            // Without a data source, we can't do this.
            if (this.DataSource == null)
                return;

            // Check that the object is in the list (plus not all data sources can locate objects)
            int index = this.DataSource.GetObjectIndex(modelObject);
            if (index < 0 || index >= this.VirtualListSize)
                return;

            // If the given model is already selected, don't do anything else (prevents an flicker)
            if (this.SelectedIndices.Count == 1 && this.SelectedIndices[0] == index)
                return;

            // Finally, select the row
            this.SelectedIndices.Clear();
            this.SelectedIndices.Add(index);
            if (setFocus)
                this.SelectedItem.Focused = true;
        }

        /// <summary>
        /// Select the rows that is displaying any of the given model object. All other rows are deselected.
        /// </summary>
        /// <param name="modelObjects">A collection of model objects</param>
        /// <remarks>This method has O(n) performance where n is the number of model objects passed.
        /// Do not use this to select all the rows in the list -- use SelectAll() for that.</remarks>
        public override void SelectObjects(IList modelObjects)
        {
            // Without a data source, we can't do this.
            if (this.DataSource == null)
                return;

            this.SelectedIndices.Clear();

            if (modelObjects == null)
                return;

            foreach (object modelObject in modelObjects) {
                int index = this.DataSource.GetObjectIndex(modelObject);
                if (index >= 0 && index < this.VirtualListSize)
                    this.SelectedIndices.Add(index);
            }
        }

        /// <summary>
        /// Set the collection of objects that this control will show.
        /// </summary>
        /// <param name="collection"></param>
        /// <remark>This method can safely be called from background threads.</remark>
        public override void SetObjects(IEnumerable collection)
        {
            if (this.InvokeRequired) {
                this.Invoke((MethodInvoker)delegate { this.SetObjects(collection); });
                return;
            }

            if (this.DataSource == null)
                return;

            this.BeginUpdate();
            try {            
                // Give the world a chance to cancel or change the assigned collection
                ItemsChangingEventArgs args = new ItemsChangingEventArgs(null, collection);
                this.OnItemsChanging(args);
                if (args.Canceled)
                    return;

                this.DataSource.SetObjects(args.NewObjects);
                this.UpdateVirtualListSize();
                this.Sort();
            }
            finally {
                this.EndUpdate();
            }
        }

        #endregion

        #region Implementation

        /// <summary>
        /// Invalidate any cached information when we rebuild the list.
        /// </summary>
        public override void BuildList(bool shouldPreserveSelection)
        {
            this.ClearCachedInfo();
            this.Invalidate();
        }

        /// <summary>
        /// Clear any cached info this list may have been using
        /// </summary>
        public virtual void ClearCachedInfo()
        {
            this.lastRetrieveVirtualItemIndex = -1;
        }

        /// <summary>
        /// Get the checkedness of an object from the model. Returning null means the
        /// model does know and the value from the control will be used.
        /// </summary>
        /// <param name="modelObject"></param>
        /// <returns></returns>
        protected override CheckState? GetCheckState(object modelObject)
        {
            if (this.CheckStateGetter != null)
                return base.GetCheckState(modelObject);

            CheckState state = CheckState.Unchecked;
            if (modelObject != null)
                this.checkStateMap.TryGetValue(modelObject, out state);
            return state;
        }

        /// <summary>
        /// Create a OLVListItem for given row index
        /// </summary>
        /// <param name="itemIndex">The index of the row that is needed</param>
        /// <returns>An OLVListItem</returns>
        public virtual OLVListItem MakeListViewItem(int itemIndex)
        {
            OLVListItem olvi = new OLVListItem(this.GetModelObject(itemIndex));
            this.FillInValues(olvi, olvi.RowObject);
            if (this.UseAlternatingBackColors) {
                if (this.View == View.Details && itemIndex % 2 == 1)
                    olvi.BackColor = this.AlternateRowBackColorOrDefault;
                else
                    olvi.BackColor = this.BackColor;

                this.CorrectSubItemColors(olvi);
            }
            
            if (this.UseHotItem && this.HotItemIndex == itemIndex)
                this.ApplyHotItemStyle(olvi);

            this.SetSubItemImages(itemIndex, olvi);
            return olvi;
        }

        /// <summary>
        /// Record the change of checkstate for the given object in the model.
        /// This does not update the UI -- only the model
        /// </summary>
        /// <param name="modelObject"></param>
        /// <param name="state"></param>
        /// <returns>The check state that was recorded and that should be used to update
        /// the control.</returns>
        protected override CheckState PutCheckState(object modelObject, CheckState state)
        {
            state = base.PutCheckState(modelObject, state);
            this.checkStateMap[modelObject] = state;
            return state;
        }

        /// <summary>
        /// Prepare the listview to show alternate row backcolors
        /// </summary>
        /// <remarks>Alternate colored backrows can't be handle in the same way as our base class.
        /// With virtual lists, they are handled at RetrieveVirtualItem time.</remarks>
        protected override void PrepareAlternateBackColors()
        {
            // do nothing
        }

        /// <summary>
        /// Refresh the given item in the list
        /// </summary>
        /// <param name="olvi">The item to refresh</param>
        public override void RefreshItem(OLVListItem olvi)
        {
            this.ClearCachedInfo();
            this.RedrawItems(olvi.Index, olvi.Index, false);
        }

        /// <summary>
        /// Change the size of the list
        /// </summary>
        /// <param name="newSize"></param>
        protected virtual void SetVirtualListSize(int newSize)
        {
            if (newSize < 0 || this.VirtualListSize == newSize)
                return;

            int oldSize = this.VirtualListSize;

            this.ClearCachedInfo();

            // There is a bug in .NET when a virtual ListView is cleared
            // (i.e. VirtuaListSize set to 0) AND it is scrolled vertically: the scroll position 
            // is wrong when the list is next populated. To avoid this, before 
            // clearing a virtual list, we make sure the list is scrolled to the top.
            // [6 weeks later] Damn this is a pain! There are cases where this can also throw exceptions!
            try {
                if (newSize == 0 && this.TopItemIndex > 0)
                    this.TopItemIndex = 0;
            }
            catch (Exception) {
                // Ignore any failures
            }

            // In strange cases, this can throw the exceptions too. The best we can do is ignore them :(
            try {
                this.VirtualListSize = newSize;
            }
            catch (ArgumentOutOfRangeException) {
                // pass
            }
            catch (NullReferenceException) {
                // pass
            }

            // Tell the world that the size of the list has changed
            this.OnItemsChanged(new ItemsChangedEventArgs(oldSize, this.VirtualListSize));
        }

        /// <summary>
        /// Take ownership of the 'objects' collection. This separates our collection from the source.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method
        /// separates the 'objects' instance variable from its source, so that any AddObject/RemoveObject
        /// calls will modify our collection and not the original colleciton.
        /// </para>
        /// <para>
        /// VirtualObjectListViews always own their collections, so this is a no-op.
        /// </para>
        /// </remarks>
        protected override void TakeOwnershipOfObjects()
        {
        }

        /// <summary>
        /// Change the size of the virtual list so that it matches its data source
        /// </summary>
        public virtual void UpdateVirtualListSize()
        {
            if (this.DataSource != null)
                this.SetVirtualListSize(this.DataSource.GetObjectCount());
        }

        #endregion

        #region Event handlers

        /// <summary>
        /// Handle the CacheVirtualItems event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void HandleCacheVirtualItems(object sender, CacheVirtualItemsEventArgs e)
        {
            if (this.DataSource != null)
                this.DataSource.PrepareCache(e.StartIndex, e.EndIndex);
        }

        /// <summary>
        /// Event handler for the column click event
        /// </summary>
        /// <remarks>
        /// <para>
        /// This differs from its base version by explicitly preserving selection.
        /// The base class (ObjectListView) stores the selection state in the ListViewItem
        /// objects, so when they are sorted, the selected-ness is automatically preserved.
        /// But a virtual list only knows which indices are selected, so the same rows are
        /// selected after sorting, even if they are showing different objects. So, we have
        /// to specifically remember which objects were selected, and then reselected them
        /// afterwards. 
        /// </para>
        /// <para>
        /// For large lists when many objects are selected, this re-selection
        /// is the slowest part of sorting the list.

⌨️ 快捷键说明

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