為了提升用戶使用體驗,特擴展此功能(來源與Xafari Framework)。
1.可在模型編輯器中設置是否啓用,默認啓用。
2.DataAccessMode為Client模式才啓用。其它模式自動關閉。
3.詳見代碼。
using DevExpress.ExpressApp; using DevExpress.ExpressApp.DC; using DevExpress.ExpressApp.Model; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; namespace CommonModule.ListViewControl.PartialLoadListView { [DefaultValue(1000)] public enum PartSize { //[Description("100")] //Rec100, //[Description("250")] //Rec250, //[Description("500")] //Rec500, [Description("1000")] Rec1000, //[Description("2500")] //Rec2500, [Description("5000")] Rec5000, [Description("All")] RecAll } public enum LoadingBehavior { Refresh, LoadPart, LoadAll } public enum ItemsStringId { StringTop, StringAll, StringAllShown, StringTopShown, StringRecords } public interface IModelListViewXafari : IModelNode,IModelExtender { [Category("Data"), DefaultValue(true), Description("If set to true, partial loading will be used.")] bool TopReturnedObjectsChangingEnabled { get; set; } } [DomainLogic(typeof(IModelListViewXafari))] public static class IModelListViewXafariLogic { public static bool TopReturnedObjectsChangingEnabled(this IModelListView modelListView) { return ((IModelListViewXafari)modelListView).TopReturnedObjectsChangingEnabled; } } }
using CommonModule.ListViewControl.PartialLoadListView; using DevExpress.Data; using DevExpress.Data.Filtering; using DevExpress.ExpressApp; using DevExpress.ExpressApp.Actions; using DevExpress.ExpressApp.Model; using DevExpress.ExpressApp.SystemModule; using DevExpress.ExpressApp.Templates; using DevExpress.ExpressApp.Utils; using DevExpress.ExpressApp.Win.Editors; using DevExpress.ExpressApp.Xpo; using DevExpress.Utils; using DevExpress.Xpo; using DevExpress.Xpo.DB; using DevExpress.XtraGrid.Columns; using DevExpress.XtraGrid.Views.Grid; using DevExpress.XtraGrid.Views.Grid.ViewInfo; using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Reflection; using System.Windows.Forms; namespace CommonModule.ListViewControl.PartialLoadListView { public class PartialLoadListViewController : ViewController<DevExpress.ExpressApp.ListView>, IModelExtender { private const string limitImage = null; private const string allImage = null; private int _partSize; private ChoiceActionItem _setPartSizeItem; private XPCollection _collection; private CollectionSourceBase _collectionSource; private bool _allShown; private int _records; private int _partCountCore = 1; private IContainer components; private SingleChoiceAction partLoadAction; public int PartCount { get { return this._partCountCore; } } public PartialLoadListViewController() { this.InitializeComponent(); base.RegisterActions(this.components); base.TargetViewType = DevExpress.ExpressApp.ViewType.ListView; this.SetupItems(); } protected override void OnActivated() { this.partLoadAction.Active.SetItemValue("Active", false); if (base.View != null && base.View.Model.DataAccessMode != CollectionSourceDataAccessMode.Client) { return; } if (this.GetModelListView() == null) { return; } base.OnActivated(); this.SetupAppearance(); } private void ViewOnControlsCreated(object sender, EventArgs eventArgs) { GridView gridView = this.GetGridView(); this.InitCollection(); this._collection.LoadingEnabled = false; this._collectionSource.TopReturnedObjects = 0; this._collectionSource.Sorting.Clear(); gridView.BeginSort(); foreach (GridColumn gridColumn in gridView.Columns) { if (gridColumn.SortOrder != ColumnSortOrder.None) { if (gridColumn.SortOrder == ColumnSortOrder.Ascending) { this._collectionSource.Sorting.Add(new SortProperty(PartialLoadListViewController.PropertyName(gridColumn), SortingDirection.Ascending)); } else { this._collectionSource.Sorting.Add(new SortProperty(PartialLoadListViewController.PropertyName(gridColumn), SortingDirection.Descending)); } } } gridView.EndSort(); this._collectionSource.TopReturnedObjects = this._records; this._collection.LoadingEnabled = true; } private IModelListViewXafari GetModelListView() { IModelListViewXafari modelListViewXafari = base.View.Model as IModelListViewXafari; if (modelListViewXafari == null || !modelListViewXafari.TopReturnedObjectsChangingEnabled) { return null; } this._records = base.View.Model.TopReturnedObjects; return modelListViewXafari; } private void SetupAppearance() { this.partLoadAction.PaintStyle = ActionItemPaintStyle.CaptionAndImage; if (base.View.Model.TopReturnedObjects != 0) { this.SetImageAndCaptionToLimitShow(); } else { this.SetImageAndCaptionToShowAllRecords(); } this.partLoadAction.Active.SetItemValue("Active", true); } protected override void OnViewControlsCreated() { base.OnViewControlsCreated(); base.View.CurrentObjectChanged += new EventHandler(this.ViewOnCurrentObjectChanged); this.InitCollection(); GridView gridView = this.GetGridView(); if (gridView != null) { gridView.Click += new EventHandler(this.GridViewOnClick); } } private static string PropertyName(GridColumn column) { IGridColumnModelSynchronizer gridColumnInfo = PartialLoadListViewController.GetGridColumnInfo(column); if (gridColumnInfo == null) { return column.FieldName; } return gridColumnInfo.PropertyName; } private static IGridColumnModelSynchronizer GetGridColumnInfo(GridColumn column) { if (column != null && column.View is IModelSynchronizersHolder) { return ((IModelSynchronizersHolder)column.View).GetSynchronizer(column) as IGridColumnModelSynchronizer; } return null; } private void GridViewOnClick(object sender, EventArgs eventArgs) { if (this._allShown || this._collectionSource.Sorting == null) { return; } MouseEventArgs mouseEventArgs = eventArgs as MouseEventArgs; if (mouseEventArgs == null || mouseEventArgs.Button != MouseButtons.Left) { return; } GridView gridView = sender as GridView; if (gridView.IsSizingState) { return; } GridHitInfo gridHitInfo = gridView.CalcHitInfo(mouseEventArgs.Location); if (gridHitInfo.HitTest == GridHitTest.ColumnFilterButton) { return; } if (gridHitInfo.InColumn) { this._collection.LoadingEnabled = false; this._collectionSource.TopReturnedObjects = 0; if (this._collectionSource.Sorting != null) { this._collectionSource.Sorting.Clear(); } else { this._collectionSource.Sorting = new List<SortProperty>(); } gridView.BeginSort(); foreach (GridColumn gridColumn in gridView.Columns) { gridColumn.SortOrder = ColumnSortOrder.None; } if (gridHitInfo.Column.SortOrder == ColumnSortOrder.None || gridHitInfo.Column.SortOrder == ColumnSortOrder.Descending) { this._collectionSource.Sorting.Add(new SortProperty(PartialLoadListViewController.PropertyName(gridHitInfo.Column), SortingDirection.Ascending)); gridHitInfo.Column.SortOrder = ColumnSortOrder.Ascending; } else { this._collectionSource.Sorting.Add(new SortProperty(PartialLoadListViewController.PropertyName(gridHitInfo.Column), SortingDirection.Descending)); gridHitInfo.Column.SortOrder = ColumnSortOrder.Descending; } gridView.EndSort(); this._collectionSource.TopReturnedObjects = this._records; this._collection.LoadingEnabled = true; base.ObjectSpace.Refresh(); DXMouseEventArgs.GetMouseArgs(mouseEventArgs).Handled = true; } } private GridView GetGridView() { GridListEditor gridListEditor = base.View.Editor as GridListEditor; if (gridListEditor == null || gridListEditor.GridView == null) { return null; } return gridListEditor.GridView; } private void ViewOnCurrentObjectChanged(object sender, EventArgs eventArgs) { base.View.CurrentObjectChanged -= new EventHandler(this.ViewOnCurrentObjectChanged); int topReturnedObjects = base.View.Model.TopReturnedObjects; if (topReturnedObjects == 0) { this.SetImageAndCaptionToShowAllRecords(); this._allShown = true; return; } this._partSize = topReturnedObjects; this.SetImageAndCaptionToLimitShow(); this.SetPartSize(); this.ResetPartCount(); this.UpdateCollection(LoadingBehavior.LoadPart); } private void SetPartSize() { if (!(base.View.Model is IModelListViewXafari)) { return; } this._partSize = base.View.Model.TopReturnedObjects; } private void InitCollection() { this._collectionSource = base.View.CollectionSource; ProxyCollection proxyCollection = this._collectionSource.Collection as ProxyCollection; if (proxyCollection == null) { return; } this._collection = (XPCollection)proxyCollection.OriginalCollection; } private void ResetPartCount() { this._partCountCore = 1; } private void UpdatePartCount() { this._partCountCore++; } private void UpdateCollection(LoadingBehavior behavior) { if (this._collection == null) { this.InitCollection(); } try { this._collection.LoadingEnabled = false; Type type = base.View.ObjectTypeInfo.Type; decimal value = Convert.ToDecimal(((XPObjectSpace)base.ObjectSpace).Session.Evaluate(type, CriteriaOperator.Parse("Count()", new object[0]), XPObjectSpace.CombineCriteria(this._collectionSource.Criteria.GetValues().ToArray()))); int num; if (behavior != LoadingBehavior.LoadAll && (this._partCountCore == 1 || behavior == LoadingBehavior.Refresh)) { num = this._records; } else if (behavior == LoadingBehavior.LoadAll) { num = (int)value; this._records = num; } else { if (this._partSize == 0) { this._partSize = this._records; } this._records += this._partSize; num = this._records; } this._collectionSource.TopReturnedObjects = num; if (behavior != LoadingBehavior.Refresh) { base.View.ObjectSpace.Refresh(); } this._collection.LoadingEnabled = true; } catch (Exception ex) { throw new Exception(ex.ToString()); } } private void SetupItems() { this.partLoadAction.Items.Clear(); this.FillItemWithEnumValues(typeof(PartSize)); } private void FillItemWithEnumValues(Type enumType) { IEnumerator enumerator = Enum.GetValues(enumType).GetEnumerator(); try { while (enumerator.MoveNext()) { object current = enumerator.Current; PartSize enumValue = (PartSize)current; ChoiceActionItem choiceActionItem = new ChoiceActionItem(Guid.NewGuid().ToString(), current); choiceActionItem.ImageName = ImageLoader.Instance.GetEnumValueImageName(current); choiceActionItem.Caption = ((DescriptionAttribute)Attribute.GetCustomAttribute(typeof(PartSize).GetFields(BindingFlags.Static | BindingFlags.Public).Single((FieldInfo x) => (PartSize)x.GetValue(null) == enumValue), typeof(DescriptionAttribute))).Description; this.partLoadAction.Items.Add(choiceActionItem); if (current.ToString() == "RecAll") { choiceActionItem.BeginGroup = true; } } } finally { IDisposable disposable = enumerator as IDisposable; if (disposable != null) { disposable.Dispose(); } } } private void partLoadAction_Execute(object sender, SingleChoiceActionExecuteEventArgs e) { if (e.SelectedChoiceActionItem.ParentItem != this._setPartSizeItem) { if (e.SelectedChoiceActionItem.Caption == "顯示更多") { this.UpdatePartCount(); this.UpdateCollection(LoadingBehavior.LoadPart); this.SetImageAndCaptionToLimitShow(); } return; } ChoiceActionItem choiceActionItem = this.partLoadAction.Items.FirstOrDefault((ChoiceActionItem a) => a.Id == "顯示更多"); if (e.SelectedChoiceActionItem.Caption == "All") { if (DialogResult.OK != MessageBox.Show("這個操作比較耗時,建議你請先設置查詢條件再執行次操作,確定執行?", "警告!", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning)) return; this.SetImageAndCaptionToShowAllRecords(); this.UpdateCollection(LoadingBehavior.LoadAll); this.partLoadAction.ToolTip = "顯示所有記錄";//XafariWinLocalizer.Active.GetLocalizedString(ItemsStringId.StringAllShown); this._allShown = true; if (choiceActionItem != null) { choiceActionItem.Enabled.SetItemValue("Enabled", false); } return; } int num = Convert.ToInt32(e.SelectedChoiceActionItem.Caption); base.View.Model.TopReturnedObjects = num; this._partSize = num; this.ResetPartCount(); this._records = this._partSize; this.UpdateCollection(LoadingBehavior.LoadPart); if (choiceActionItem != null) { choiceActionItem.Enabled.SetItemValue("Enabled", true); } this.SetImageAndCaptionToLimitShow(); this._allShown = false; } protected override void OnDeactivated() { GridView gridView = this.GetGridView(); if (gridView != null) { gridView.Click -= new EventHandler(this.GridViewOnClick); } base.OnDeactivated(); } private void SetImageAndCaptionToShowAllRecords() { this.partLoadAction.ImageName = null; this.partLoadAction.Caption = "All";// XafariWinLocalizer.Active.GetLocalizedString(ItemsStringId.StringAll); this.partLoadAction.ToolTip = "顯示所有記錄";//XafariWinLocalizer.Active.GetLocalizedString(ItemsStringId.StringAllShown); } private void SetImageAndCaptionToLimitShow() { this.partLoadAction.ImageName = null; this.partLoadAction.Caption = string.Format("{0} {1} ", "僅顯示前", this._records); this.partLoadAction.ToolTip = string.Format("{0} {1} {2}.", "僅顯示前", this._records, "條記錄"); } protected override void Dispose(bool disposing) { if (disposing && this.components != null) { this.components.Dispose(); } base.Dispose(disposing); } private void InitializeComponent() { this.components = new Container(); this.partLoadAction = new SingleChoiceAction(this.components); this.partLoadAction.ItemType = SingleChoiceActionItemType.ItemIsOperation; this.partLoadAction.Caption = "部分顯示"; this.partLoadAction.ConfirmationMessage = null; this.partLoadAction.EmptyItemsBehavior = EmptyItemsBehavior.None; this.partLoadAction.Id = "partLoadAction"; this.partLoadAction.PaintStyle = ActionItemPaintStyle.CaptionAndImage; this.partLoadAction.ShowItemsOnClick = true; this.partLoadAction.ToolTip = string.Empty; this.partLoadAction.Execute += new SingleChoiceActionExecuteEventHandler(this.partLoadAction_Execute); } public void ExtendModelInterfaces(DevExpress.ExpressApp.Model.ModelInterfaceExtenders extenders) { extenders.Add<IModelViews, IModelListViewXafari>(); extenders.Add<IModelListView, IModelListViewXafari>(); } } }