以下內容全部為web版本的老模板風格下完成。
一、在編輯狀態的詳細視圖下打印報表。
有些時候,需要在編輯狀態下直接打印報表內容,官方默認是不允許這樣做的。用Reflector查看源碼,可以看到:
Declaring Type: DevExpress.ExpressApp.ReportsV2.PrintSelectionBaseController Assembly: DevExpress.ExpressApp.ReportsV2.v16.1, Version=16.1.5.0protected virtual void UpdateActionState() { if (base.View != null) { this.ShowInReportAction.Enabled["DisableActionWhenThereAreChanges"] = true; if (this.ShowInReportActionEnableMode == ActionEnabledMode.ModifiedChanged) { this.ShowInReportAction.Enabled["DisableActionWhenThereAreChanges"] = !base.View.ObjectSpace.IsModified; } else if ((this.ShowInReportActionEnableMode == ActionEnabledMode.ViewMode) && (base.View is DetailView)) { this.ShowInReportAction.Enabled["DisableActionWhenThereAreChanges"] = ((DetailView) base.View).ViewEditMode == ViewEditMode.View; } } }
在這個方法中禁止了顯示按鈕的邏輯。
ShowInReportActionEnableMode 是在構造函數中做了初始化,如下:
public PrintSelectionBaseController() { base.TypeOfView = typeof(ObjectView); this.showInReportAction = new SingleChoiceAction(this, "ShowInReportV2", PredefinedCategory.Reports); this.showInReportAction.Caption = "Show in Report"; this.showInReportAction.ToolTip = "Show selected records in a report"; this.showInReportAction.Execute += new SingleChoiceActionExecuteEventHandler(this.showInReportAction_Execute); this.showInReportAction.ItemType = SingleChoiceActionItemType.ItemIsOperation; this.showInReportAction.SelectionDependencyType = SelectionDependencyType.RequireMultipleObjects; this.showInReportAction.ImageName = "Action_Report_Object_Inplace_Preview"; this.ShowInReportActionEnableMode = ShowInReportActionEnableModeDefault; //<<<<---------------看這裡 }
ShowInReportActionEnableModeDefault 是一個靜態變量。
public static ActionEnabledMode ShowInReportActionEnableModeDefault;
也就是說,可以全局設定行為。 再來詳細的看一下如何顯示的邏輯:
protected virtual void UpdateActionState() { if (base.View != null) { this.ShowInReportAction.Enabled["DisableActionWhenThereAreChanges"] = true; //默認可以用,但這個名稱取的和值是不是很難理解? if (this.ShowInReportActionEnableMode == ActionEnabledMode.ModifiedChanged) //標注1 { this.ShowInReportAction.Enabled["DisableActionWhenThereAreChanges"] = !base.View.ObjectSpace.IsModified; } else if ((this.ShowInReportActionEnableMode == ActionEnabledMode.ViewMode) && (base.View is DetailView)) //這個模式下,只有當前詳細視圖是查看時才能用。 { this.ShowInReportAction.Enabled["DisableActionWhenThereAreChanges"] = ((DetailView) base.View).ViewEditMode == ViewEditMode.View; } } }
標注1:如果 模式設置為ModifiedChanged則, 有編輯的對象,就不可以用這個按鈕。看到這裡你一定認為,官方不是支持了編輯狀態的打印報表了嗎?然而,這個ObjectSpace.IsModified的值在沒,有編輯時也經常會變為true,即使是剛剛按過保存按鈕。
我認為用這個值做判斷很難控制,不如直接改掉吧。
多說一句,官方的考慮是正確的,如:你剛剛修改了內容,沒按保存去打印單據,那麼結果可能數據庫裡的內容和打印的結果是不一致的。
所以我們進行一下改造。
public class PrintReportController : PrintSelectionBaseController { protected override void UpdateActionState() { if (View is DetailView) { //詳細視圖下,都是可用的 } else { base.UpdateActionState(); //如果不是detailview時,還按原來的邏輯走 } } protected override void ShowInReport(SingleChoiceActionExecuteEventArgs e, string reportContainerHandle) { var dv = View as DetailView; if (dv != null && dv.ViewEditMode == DevExpress.ExpressApp.Editors.ViewEditMode.Edit) { this.ObjectSpace.CommitChanges(); }//執行按鈕前,先保存一下數據 base.ShowInReport(e, reportContainerHandle); } }
就是這麼簡單。
二、讓查看狀態的視圖支持“返回”到上一個視圖的功能。
這個相當簡單,當做初學者的學習示例吧,但用戶還是很需要這個功能的。
public partial class CloseDetailViewController : ViewController<DetailView> { public CloseDetailViewController() { InitializeComponent(); this.CloseViewModeDetail.Execute += CloseViewModeDetail_Execute; // Target required Views (via the TargetXXX properties) and create their Actions. } private void CloseViewModeDetail_Execute(object sender, SimpleActionExecuteEventArgs e) { this.View.Close(); } protected override void OnActivated() { base.OnActivated(); this.CloseViewModeDetail.Active["InViewMode"] = View.ViewEditMode == ViewEditMode.View; //這個按鈕只有在查看狀態中顯示 // Perform various tasks depending on the target View. } protected override void OnViewControlsCreated() { base.OnViewControlsCreated(); // Access and customize the target View control. } protected override void OnDeactivated() { // Unsubscribe from previously subscribed events and release other references and resources. base.OnDeactivated(); } }
//按鈕是這樣設置的:
this.CloseViewModeDetail.Caption = "返回"; this.CloseViewModeDetail.Category = "Export"; this.CloseViewModeDetail.Id = "CloseViewModeDetail";
三、在編輯狀態的主表點擊明細表時直接轉到編輯狀態
這個功能也很實用,因為點擊編輯按鈕有點累,按鈕圖標太小,如果點擊任意行位置,彈出的是查看狀態的記錄內容。所以現在改變為,如果是編輯狀態的主表,彈出的也是編輯狀態的界面。
public partial class DetailItemViewController : ViewController<DetailView> { public DetailItemViewController() { InitializeComponent(); } protected override void OnActivated() { base.OnActivated(); var os = this.ObjectSpace as XPNestedObjectSpace; //如果有上級詳細視圖並且是在編輯狀態的視圖,那把本級別的編輯視圖也設置成編輯狀態。 if (os!=null) { var dv = os.ParentObjectSpace.Owner as DetailView; if (dv!=null) { this.View.ViewEditMode = dv.ViewEditMode; } } // Perform various tasks depending on the target View. } protected override void OnViewControlsCreated() { base.OnViewControlsCreated(); // Access and customize the target View control. } protected override void OnDeactivated() { // Unsubscribe from previously subscribed events and release other references and resources. base.OnDeactivated(); } }
現在XAF中支持的列表自由編輯還有有很多不支持的功能,這樣折中處理一下也不錯。