[原] XAF 如何启用ListView Top N records 提升用户使用体验

时间:2022-12-04 10:00:24

為了提升用戶使用體驗,特擴展此功能(來源與Xafari Framework)。
1.可在模型編輯器中設置是否啓用,默認啓用。
2.DataAccessMode為Client模式才啓用。其它模式自動關閉。
3.詳見代碼。

4.當有篩選條件時有Bug,還有待解決,才能上綫使用!

[原] XAF 如何启用ListView Top N records  提升用户使用体验

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()]
public enum PartSize
{
//[Description("100")]
//Rec100,
//[Description("250")]
//Rec250,
//[Description("500")]
//Rec500,
[Description("")]
Rec1000,
//[Description("2500")]
//Rec2500,
[Description("")]
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 = ;
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 = ;
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 != )
{
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 = ;
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 == )
{
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 = ;
}
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[]), XPObjectSpace.CombineCriteria(this._collectionSource.Criteria.GetValues().ToArray())));
int num;
if (behavior != LoadingBehavior.LoadAll && (this._partCountCore == || behavior == LoadingBehavior.Refresh))
{
num = this._records;
}
else if (behavior == LoadingBehavior.LoadAll)
{
num = (int)value;
this._records = num;
}
else
{
if (this._partSize == )
{
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>();
}
} }