// create the DatabaseReportStorage class which used to override the save, save as function.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DevExpress.XtraReports.UI;
using DevExpress.XtraReports.Extensions;
using System.Windows.Forms;
using System.ComponentModel;
using System.IO;
using riteweigh.nettiers.Entities;
using riteweigh.core.framework;
using SimpleEventBroker;
using Riteweigh.Easiweigh.forms.Base;
namespace Riteweigh.Easiweigh.forms.report
{
public class DatabaseReportStorage : ReportStorageExtension
{
private TList<ReportLayout> reportList = null;
public TList<ReportLayout> ReportList
{
get { return reportList; }
set { reportList = value; }
}
private ReportAdminGridForm parentForm = null;
public DatabaseReportStorage(IEnumerable<ReportLayout> list,ReportAdminGridForm f)
{
reportList = list as TList<ReportLayout>;
parentForm = f;
}
// invoke when click the save button (if the report is new created) and also click the save as button
public override string SetNewData(XtraReport report, string defaultUrl)
{
StorageEditorForm form = CreateForm();
form.textBox1.Text = defaultUrl;
form.listBox1.Enabled = false;
if (form.ShowDialog() == DialogResult.OK)
{
string url = form.textBox1.Text;
if (!string.IsNullOrEmpty(url) && !form.listBox1.Items.Contains(url))
{
TypeDescriptor.GetProperties(typeof(XtraReport))["DisplayName"].SetValue(report, url);
SetNewData2(report, url);
return url;
}
else
{
MessageBox.Show("Incorrect report name", "Error",
MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
}
}
return string.Empty;
}
// save the report to DB
public void SetNewData2(XtraReport report, string url)
{
ReportLayout layout = FindReport(url);
if (layout != null)
{
layout.Layout = GetBuffer(report);
layout.UpdateDate = DateTime.Now;
}
else
{
layout = new ReportLayout();
layout.Layout = GetBuffer(report);
layout.ReportCategoryId = 2; // custom
layout.ReportLayoutUrl = url;
layout.CreatedDate = DateTime.Now;
layout.UpdateDate = DateTime.Now;
}
parentForm.OnSaveReport(layout);
report.Name = url;
}
// invoked when save change for exist report (if the report is existed) (save button)
public override void SetData(XtraReport report, string url)
{
/*
* if the exist report is system report, create a new report
* else save the change of the exist report
*/
ReportLayout layout = FindReport(url);
if (layout != null)
{
if (layout.ReportCategoryId == 2) // custom report
{
layout.Layout = GetBuffer(report);
layout.UpdateDate = DateTime.Now;
}
else // system report -- need create new report (go to the function save as)
{
SetNewData(report,report.Name + "NEW");
}
}
else
{
layout = new ReportLayout();
layout.Layout = GetBuffer(report);
layout.ReportLayoutUrl = url;
layout.CreatedDate = DateTime.Now;
layout.UpdateDate = DateTime.Now;
}
//parentForm.OnSaveReport(layout); save the layout to db
report.Name = url;
}
public ReportLayout FindReport (string url)
{
foreach (ReportLayout report in reportList)
{
if (report.ReportLayoutUrl == url)
{
return report;
}
}
return null;
}
StorageEditorForm CreateForm()
{
StorageEditorForm form = new StorageEditorForm();
foreach (ReportLayout report in reportList)
form.listBox1.Items.Add(report.ReportLayoutUrl);
return form;
}
// user click open on design form
public override string GetNewUrl()
{
StorageEditorForm form = CreateForm();
form.textBox1.Enabled = false;
if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
return form.textBox1.Text;
return string.Empty;
}
// user select a report and then click OK on storageEditForm. (open a exist report on a new tab)
public override byte[] GetData(string url)
{
ReportLayout reportLayout = FindReport(url);
MemoryStream stream = new MemoryStream(reportLayout.Layout);
XtraReport report = RestoreReport(stream);
report.Name = url;
return GetBuffer(report);
}
public override bool CanSetData(string url)
{
return true;
}
public override bool IsValidUrl(string url)
{
return !string.IsNullOrEmpty(url);
}
public override bool GetStandardUrlsSupported(ITypeDescriptorContext context)
{
return true;
}
//public override string[] GetStandardUrls(ITypeDescriptorContext context)
//{
// //if (context != null && context.Instance is XRSubreport)
// //{
// // XRSubreport xrSubreport = context.Instance as XRSubreport;
// // if (xrSubreport.RootReport !=
// // null && xrSubreport.RootReport.Extensions.TryGetValue("StorageID", out storageID))
// // {
// // List<string> result = GetUrlsCore(CanPassId);
// // return result.ToArray();
// // }
// //}
// List<string> urls = new List<string>();
// foreach (ReportLayout Layout in ReportList)
// {
// urls.Add(Layout.ReportLayoutUrl);
// }
// return urls.ToArray() ;
//}
public byte[] GetBuffer(XtraReport report)
{
return StoreReportToStream(report).ToArray();
}
public MemoryStream StoreReportToStream(XtraReport report)
{
MemoryStream stream = new MemoryStream();
report.SaveLayout(stream);
return stream;
}
//restore report layout from a stream
public XtraReport RestoreReport(MemoryStream stream)
{
// Create a report from the stream.
return XtraReport.FromStream(stream, true);
}
}
}
// create a form to popup when user click save button (save the report to db) or open button (allow user select the report to show.) on end user design form.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Riteweigh.Easiweigh.forms.report
{
public partial class StorageEditorForm : Form
{
public StorageEditorForm()
{
InitializeComponent();
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
textBox1.Text = listBox1.SelectedItem.ToString();
}
private void StorageEditorForm_Load(object sender, EventArgs e)
{
if (listBox1.Items.Count > 0 && string.IsNullOrEmpty(textBox1.Text))
listBox1.SelectedIndex = 0;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
buttonOK.Enabled = !string.IsNullOrEmpty(textBox1.Text);
}
private void buttonOK_Click(object sender, EventArgs e)
{
}
}
}
// how to use :
// declare the DatabaseReportStorage class
DatabaseReportStorage reportStorage = new DatabaseReportStorage(reportList, this); // TList<ReportLayout> -> database entity
ReportStorageExtension.RegisterExtensionGlobal(reportStorage);
// create end new user designer
[SubscribesTo(UICommands.AddNewReport)]
public void OnAddNewReport(object sender, EventArgs e)
{
XRDesignForm form = new XRDesignForm();
form.ShowDialog();
}
// load a exist report and show in end user designer, allow user to change the design
[SubscribesTo(UICommands.EditReport)]
public void OnEditReport(object sender, EventArgs e)
{
var args = e as EntityEventArgs;
if (args != null && args.Entity != null)
{
XRDesignForm form = new XRDesignForm();
//MemoryStream stream = new MemoryStream(((ReportLayout)args.Entity).Layout);
//XtraReport report = RestoreReport(stream);
//form.OpenReport(report);
form.OpenReport(((ReportLayout)args.Entity).ReportLayoutUrl); //parameter is url(report name), don't know why ??
form.ShowDialog();
}
}
// load a report and show in preview dialog
[SubscribesTo(UICommands.ViewReport)]
public void OnViewReport(object sender, EventArgs e)
{
var args = e as EntityEventArgs;
if (args != null && args.Entity != null)
{
MemoryStream stream = new MemoryStream(((ReportLayout)args.Entity).Layout);
XtraReport report = RestoreReport(stream);
report.ShowPreviewDialog();
}
}
//store report to stream
private MemoryStream StoreReportToStream(XtraReport report)
{
MemoryStream stream = new MemoryStream();
report.SaveLayout(stream);
return stream;
}
//restore report layout from a stream
private XtraReport RestoreReport(MemoryStream stream)
{
// Create a report from the stream.
return XtraReport.FromStream(stream, true);
}
// delete a report
[SubscribesTo(UICommands.DeleteReport)]
public void OnDeleteReport(object sender, EventArgs e)
{
var args = e as EntityEventArgs;
if (args != null && args.Entity != null)
{
args.Result = FrameworkManager.ReportManager.Delete(args.Entity as ReportLayout);
if (args.Result)OnRaiseRefreshReportList();
}
}
// save report
[SubscribesTo(UICommands.SaveReport)]
public void OnSaveReport(object sender, EventArgs e)
{
var args = e as EntityEventArgs;
if (args != null && args.Entity != null)
{
args.Result = FrameworkManager.ReportManager.Save(args.Entity as ReportLayout);
if (args.Result) OnRaiseRefreshReportList();
}
}
// db
CREATE TABLE [dbo].[tbl_report_layout](
[report_layout_id] [int] IDENTITY(1,1) NOT NULL,
[report_layout_url] [nvarchar](50) COLLATE Latin1_General_CI_AS NOT NULL,
[layout] [varbinary](max) NOT NULL,
[created_date] [datetime] NOT NULL,
[report_category_id] [int] NOT NULL CONSTRAINT [DF_tbl_report_layout_report_category_id] DEFAULT ((2)),
[update_date] [datetime] NOT NULL CONSTRAINT [DF_tbl_report_layout_Modified] DEFAULT (getdate()),
//example save db to a dataset
http://www.devexpress.com/Support/Center/e/E2704.aspx
http://tv.devexpress.com/#XtraReportsWinFormsSavingReports;XtraReports+Suite.product;1