以下內容全部為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中支持的列表自由編輯還有有很多不支持的功能,這樣折中處理一下也不錯。