Hide export format in RDLC/SSRS Report Viewer control
I recently needed to hide or disable PDF format in Export Formats dropdown list displayed in SSRS ReportViewer’s toolbar in Local Report mode.
Unfortunately, ReportViewer control has no method or property to manage specific format’s visibility and this is true also for the recently released Report Viewer 10.
We can use Report Viewer’s property ShowExportControls to hide the export formats dropdown list but not a specific format such as PDF.
In Local Report mode, there are 2 export formats (Excel and PDF) and more Rendering Extensions for Server Report mode are available.
We have the option to hide export formats control and implement our own list. this article might help on this.
Finally, I ended up with adding new extension method SetExportFormatVisibility to ReportViewer control which uses private Reflection to disable/enable export formats.
This method is inspired by Stephen Songer’s blog post Disable/Enable export format in SSRS and ASP.NET.
The code consists of two parts, one is ReportViewerExtensions class which has SetExportFormatVisibility extension method and the second is ReportViewerExportFormat Enum to specify available export formats.
public static class ReportViewerExtensions
{
public static void SetExportFormatVisibility(this ReportViewer viewer, ReportViewerExportFormat format, bool isVisible)
{
string formatName = format.ToString();
const System.Reflection.BindingFlags Flags = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance;
System.Reflection.FieldInfo m_previewService = viewer.LocalReport.GetType().GetField("m_previewService", Flags);
System.Reflection.MethodInfo ListRenderingExtensions = m_previewService.FieldType.GetMethod("ListRenderingExtensions", Flags);
object previewServiceInstance = m_previewService.GetValue(viewer.LocalReport);
IList extensions = (IList)ListRenderingExtensions.Invoke(previewServiceInstance, null);
System.Reflection.PropertyInfo name = extensions[0].GetType().GetProperty("Name", Flags);
//object extension = null;
foreach (var ext in extensions)
{
if ((string.Compare(name.GetValue(ext, null).ToString(), formatName, true) == 0))
{
System.Reflection.FieldInfo m_isVisible = ext.GetType().GetField("m_isVisible", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
System.Reflection.FieldInfo m_isExposedExternally = ext.GetType().GetField("m_isExposedExternally", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
m_isVisible.SetValue(ext, isVisible);
m_isExposedExternally.SetValue(ext, isVisible);
break;
}
}
}
}
public enum ReportViewerExportFormat
{
Excel,
PDF
}
Simple to use..
ReportViewer1.SetExportFormatVisibility(ReportViewerExportFormat.PDF, false);
Windows 7 – Sticky Notes
Is it the time to leave my pen, sticky clips and such physical and paper-based stuff when I am writing my daily notes?
Windows 7 introduced new feature Sticky Notes which enables Windows users to write their notes on the top of Windows Desktop.
You can open Sticky Notes through Start Menu => Accessories as you can see in the figure at the left.
As the below figure shows, User has the ability to create multiple notes and colorize each one of them with a different color (arrow 3).
Also user has the option to re-size a Note’s area separately from the other Notes.
To add a new Note click on + sign (arrow 1) or just press Ctrl + N. Also you can delete the active Note by clicking on X sign (arrow 2) or pressing Ctrl + D.
Enjoy…
Entity Framework and LINQ to SQL Paging
In some applications when we need to display large sets of data , Data Paging is our choice in order to improve the performance. For ASP.NET developers we can use Data Paging mechanism provided by the most of ASP.NET Data-bound Controls such as GridView.
The default behavior of ASP.NET Data Controls is to bring the complete data set and do the paging at the application server side. This will led to network overload and server memory consuming every time user requests new data page.
Paging at the database level is mostly the best way to optimize the performance. The idea behind database level paging is to build the appropriate SQL query which brings the needed data page rather than the complete data set.
Entity Framework and LINQ to SQL provide developers with the ability to extend their SQL generator functionality to build paging enabled queries through extending IQueryable<T> interface implementation.
Here is the IQueryable<T> function as described in MSDN:
The IQueryable<T> interface enables queries to be polymorphic. That is, because a query against an IQueryable data source is represented as an expression tree, it can be executed against different types of data sources.
In this article, I am going to create a new Extended Method to offer Paging functionality to Entity Framework and LINQ to SQL query providers.
After this is completed we should be able to use Page method as the below figure shows
Page Method Signature
public static IQueryable<T> Page<T, TResult> (this IQueryable<T> query,
int pageNum, int pageSize,
Expression<Func<T, TResult>> orderByProperty,
bool isAscendingOrder,
out int rowsCount
)
Page method takes 2 generic types T and TResult. T is the type of the data in the data source to be paged and TResult is the return value of the method encapsulated by Func<T, TResult> Delegate.
query parameter is the Object Query where paging should be applied, pageNum parameter is the data page to retrieve, pageSize is the number of rows to be retrieved per data page, orderByProperty is the T type property to sorted by and it is defined as a Lambda Expression to avoid passing orderByProperty parameter as a string, isAscendingOrder identifies if the sorting is ASC or DESC and rowsCount is the count of rows in the complete data set. this will help on creating UI Data Pager in the Presentation Layer
rowsCount parameter is defined as out which requires rowsCount to be assigned to a value before the Page method returns.
Page Method Implementation
First off, I am validating the parameters as the following:
pageSize should be greater than zero, otherwise an Argument Out Of Range Exception thrown or a default value provided. The default value might be the rowsCount or a data page size predefined. In this example I’ll use 20 as the default page size.
pageNum should be greater than zero, otherwise pageNum is defined as 1. In case of pageSize is greater than or equals to rowsCount, 1 will be used as the pageNum.
I will use the query providers Take, Skip and OrderBy methods to get the correct data page according to the current page number and page size.
Let’s show how Skip and Take methods differ when mapped to SQL code. I am using LINQPad to get the equivalent SQL code.
If we write the below code
Customers.Take(5)
Equivalent SQL code looks like
SELECT TOP (5) [t0].[ID], [t0].[Name] FROM [Customers] AS [t0]
And for
Customers.Skip(5)
The result is
-- Region Parameters
DECLARE @p0 Int SET @p0 = 5
-- EndRegion
SELECT [t1].[ID], [t1].[Name]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [t0].[ID], [t0].[Name]) AS [ROW_NUMBER], [t0].[ID], [t0].[Name]
FROM [Customers] AS [t0]
) AS [t1]
WHERE [t1].[ROW_NUMBER] > @p0
ORDER BY [t1].[ROW_NUMBER]
Page Method Complete Code
public static IQueryable<T> Page<T, TResult>(this IQueryable<T> query,
int pageNum, int pageSize,
Expression<Func<T, TResult>> orderByProperty,
bool isAscendingOrder, out int rowsCount)
{
if (pageSize <= 0) pageSize = 20;
rowsCount = query.Count();
if (rowsCount <= pageSize || pageNum <= 0) pageNum = 1;
int excludedRows = (pageNum - 1) * pageSize;
if (isAscendingOrder)
query = query.OrderBy(orderByProperty);
else
query = query.OrderByDescending(orderByProperty);
return query.Skip(excludedRows).Take(pageSize);
}
excludedRows is the set of rows should be skipped using Skip method and computed as pageSize multiplied by (pageNum – 1)
I’d like to know your suggestions…
Visual Studio 2010 Report Designer doesn’t support SSRS 2005 format
Note: This issue should be resolved by converting VS 2008 (SSRS 2005) RDLCs to VS 2010 (SSRS 2008) RDLCs and adding Microsoft.ReportViewer.WebForms.dll Version 10 reference to your .NET Framework 3.5 project’s references instead of Version 9
Thanks to the Framework Multi-Targeting new feature of Visual Studio 2010 which enables .NET developers to develop .NET applications which target the previous versions of .NET Framework using Visual Studio 2010.
Based on this, I have decided to remove all previous Visual Studio versions and install Visual Studio 2010.
By the way, I have struggled to uninstall Visual Studio 2008. When I used the regular uninstall through Windows Control Panel. I have got a message which says something like “Can’t uninstall Visual Studio 2008″.
After few trials to find what is the wrong with my system, I did a quick search I found that this problem raised due to some Visual Studio 2008 hot fixes and updates which cannot be removed by the normal uninstall process. Therefore Microsoft provides Auto Uninstall Tool to completely remove Visual Studio 2008.
If you run this tool, the below screen will be displayed. just click Yes to start the cleaning process.
Let’s get back to the main reason I did this blog post for. I used Visual Studio 2010 to open ASP.NET application developed using .NET Framework 3.5. I got the below message when I tried to open RDLC report.
This message asks if I want to convert RDLC report format to 2008. After I canceled the conversion, the report designer showed “The version of the report definition language (RDL) is not support by Visual Studio 2010 Report Designer” message as you can see at the following figure
This problem happens due to Visual Studio 2008 Report Designer uses SQL Server Reporting Service (SSRS) 2005 format to work with RDLC reports and Visual Studio 2010 uses SSRS 2008 format.
It supposed that Report Designer 2010 has the ability to open and edit the previous RDLC formats for the sake of back compatibility.
I recalled that after SSRS 2008 was released, developers were not able to create RDLC reports in 2008 format and the reason of that is Visual Studio 2008 released before SQL Server 2008!.
However, I still have the ability to convert the report to RDLC 2008 format which is weird. .NET Framework 3.5 “Microsoft Report Viewer” control doesn’t support RDLC 2008 format in Local mode.
The following figure shows the message you’ll get if you try to run RDLC 2008 report under .NET Framework 3.5.
The question here is: Why I can convert RDLC 2005 to RDLC 2008 whereas I still use .NET Framework 3.5?!
Redmine, Bug Tracking and Flexible Project Management Tool
A while ago, me and some of my colleagues were talking about Bug Tracking systems in order to enhance and enforce Quality Assurance and to have a well-organized and easy to use bug reporting and monitoring tool.
There are many open source web-based bug tracking systems such as Bugzilla, Trac, BugTracker.NET and more …
Some of bug and issue tracking systems extend its functionality to cover Project Management area such as Redmine.
You might take a look at comparison of issue tracking systems.
As my team already has installed Redmine, In this article, I’m going to summarize its features.
Redmine is free, open source and cross-platform Bug Tracking and Project Management tool developed using Ruby on Rails . It provides features like Gantt chart and Calendar to manage project schedule, start and end dates of project’s elements, show dependencies and that stuff related to project management.
I quoted Redmine’s features as it mentioned in Redmine web site:
* Multiple projects support
* Flexible role based access control
* Flexible issue tracking system
* Gantt chart and calendar
* News, documents & files management
* Feeds & email notifications
* Per project wiki
* Per project forums
* Time tracking
* Custom fields for issues, time-entries, projects and users
* SCM integration (SVN, CVS, Git, Mercurial, Bazaar and Darcs)
* Issue creation via email
* Multiple LDAP authentication support
* User self-registration support
* Multilanguage support
* Multiple databases support
You can find more information about these features through Redmine features and an online demo here.
Redmine can be deployed using a native installer, as a virtual machine, in the cloud or as a module over an already installed infrastructure Stack as described in BitNami Redmine Stack.
Bug Bug!
Snowboarding, What a Pleasure?
Since around 4 or 5 months, I went through discovery session to learn the basics of snowboarding in Ski Dubai.
Ski Dubai is an indoor ski resort with 22,500 square meters of indoor ski area which is located in Dubai, UAE as a part of Mall of the Emirates.
I recalled this trip during surfing my photos tonight and I just want to share some of them with you.
Working Hours Monthly
Organizations always try to manage their employees performance to make do of them which will lead to increased revenue and customer trustworthy.
I am working now on such application called Time Capturing System (TCS). TCS allows employees to charge their time against a project from their profiles.
TCS ends up with some complicated reports such as Cost Recovery Tool (CRT) and some Utilization Reports. Therefore, I need to compute the working hours for every month.
I wrote a method named MonthWorkingHours. The method assumes that Weekend days are Friday and Saturday and Working Hours per day is 8 hours, So working hours per month = Business days * Working hours per day.
MonthWorkingHours takes year and month as parameters and returns month working hours as Int.
Note that you might need to pass working hours per day and weekend days to the method which I ignored here for the sake of simplicity.
public int MonthWorkingHours(int year, int month)
{
// days in month
int monthDays = DateTime.DaysInMonth(year,month);
//month end date
DateTime endDate = new DateTime(year,month,monthDays);
//current day by default is the start date
DateTime currentDay = new DateTime(year, month, 1);
int workingDays = 0;
//check if the current day is weekend day
while (currentDay <= endDate)
{
if (currentDay.DayOfWeek != DayOfWeek.Friday &&
currentDay.DayOfWeek != DayOfWeek.Saturday)
{
workingDays++;
}
currentDay = currentDay.AddDays(1);
}
return workingDays * 8; // 8 is working hours per day
}
This is not the complete story, you might need to exclude Public Holidays from the business days and the like.
Happy Weekend…
Real Time Web Analytics
Awesome! once you register in http://getclicky.com you’ll take advantage of real time tracking your web site’s traffic.
Also you can display its stats on your web site as a widget.
Free account provides only tracking of one web site.
Format Your Code to Publish on Web
When we write code such as C# to publish on our blogs or web sites, it’s better to format it using CSS and HTML instead of screen-shot the code. this provides copy and paste functionality.
The best way is to automate the process of formatting the code. Most of forums, blogs and web sites provide some specific tags to format your code, but if no we need to find a work-around to achieve this.
After a quick search on the web I found web site which provides such functionality for C#, VB, T-SQL, ASPX, XML and HTML along with options such as line numbers, alternate line background and embed style-sheet.
You can also download .Net Source Code for this application and extent the functionality. for example I needed to format my code with Inline CSS style.
Also there are some helpful tools such as Markdown
Happy Styling…
Tweet to Email
My friend Ali Bin Yahia has taken a good step to extend Twitter functionality. Ali published his new web site Tweet to Email which will enable Twitter users to send tweets to their Non-Twitter friends.
Tweet to Email enables its users to add groups. each group of them would contain a list of emails and tagged by predefined hash tags such as #TM1.
You need to add your Twitter Id to your Tweet to Email profile and to add the right hash tag to your tweet.
Tweet to Email checks Twitter every 2 minutes. Messages would be sent based on Twitter Id and the Hash Tag mentioned in the tweet.












