Solved

How can I capture a data field from a specific X, Y coordinate (Hit Test) in a Crystal Report Viewer or Report Document?

Posted on 2011-09-28
21
733 Views
Last Modified: 2012-05-12
I have a .NET project that is using Crystal Decisions CrystalReportViewer and ReportDocument objects to display a Crystal report. I am handling the mouse click event to capture the coordinates and execute some procedures based on what the user has clicked within the report.
Is there anyway to pass the mouse coordinates to the Report Viewer or Report Document do figure out what the user has clicked on?
I have found an object type called CrystalDecisions.Windows.Forms.ReportObjectHitTest, but I have no clue how to use it, and I could not find any documentation that talks about it.
I know its possible to get some info out from the report using the Drill Event, but that only works for groups on properly formatted reports.
0
Comment
Question by:aferia
  • 10
  • 8
  • 2
  • +1
21 Comments
 
LVL 100

Expert Comment

by:mlmcc
ID: 36717339
I am not aware of any way to do that.

What version of Crystal and VS?

mlmcc
0
 

Author Comment

by:aferia
ID: 36717395
Visual Studio 2008, Crystal 10.
I think that I am close to a solution - I have found this shared function:
CrystalDecisions.Windows.Forms.ReportObjectHitTest.GetObjectFromPoint(position, page)
Now I cant figure out how to get the page object out from the Report Viewer/Document. I'm thinking that this is a "do-nothing" function... they must have implemented the interface without functionality, which is ridonkulous.
0
 
LVL 100

Expert Comment

by:mlmcc
ID: 36717469
It may also have been something they tried to get to work and couldn't make it work.  They forgot to remove/change the interface.

mlmcc
0
Resolve Critical IT Incidents Fast

If your data, services or processes become compromised, your organization can suffer damage in just minutes and how fast you communicate during a major IT incident is everything. Learn how to immediately identify incidents & best practices to resolve them quickly and effectively.

 
LVL 2

Expert Comment

by:Robert Silver
ID: 36717849
1. You can create a aspx or Java applet  and
a javascript on mouse button up or down to capture the current position x,y and  store in
a hidden field(s) you can then pass the parameter  into the Crystal Report via a the running of the report
from as submit button action.

Note that the screenX and screenY properties provide the coordinates you may be seeking.
you can test this by creating a javascript mouse button handler and use alerts to debug e.g

var MyEventerObj = {
   addHandler: function(element, type, handler){
       if (element.addEventListener){
            element.addEventListener(type, handler, false);
          }
          else if (element.attachEvent)
          { element.attachEvent("on" + type, handler); }
          else { element["on" + type] = handler; }
          },

          removeHandler: function(element, type, handler)
          {
              if (element.removeEventListener)
            {
               element.removeEventListener(type, handler, false);
            } else if (element.detachEvent)
            { element.detachEvent("on" + type, handler); }
            else { element["on" + type] = null; }
          }
            
};


var div=document.getElementById("idvalueofmine");
MyEventerObj.addHandler(div,"click",    function(event) {
                                                                                         event=MyEventerObj.getEvent(event);
                                                                                         alert("screen coordintes:" +  
                                                                                         event.screenX + "," + event.screenY);
                                                                                     }
                                      ));


Hope that helps
Just store the value instead of alert outputing
0
 

Author Comment

by:aferia
ID: 36718001
I'm sorry. I should have mentioned that this is for VB or C# .NET. But it looks like the ASP code would not have behavior that I'm looking for either way. I'm trying to mimic the drill-down behavior that is built-in Crystal reports, but without the need to group and hiding details in the crystal designer.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 36780057
Are you looking for something like the Drill event handler?

CrystalReportViewer.Drill Event
http://msdn.microsoft.com/en-us/library/ms227063.aspx
0
 

Author Comment

by:aferia
ID: 36815123
Kinda - the drilldown event does not get fired unless the report is configured with groups and such.
I have a simple report that lists Customers - I would like to like to handle an event that lets me know when a user clicks on a Customer #.
When I am using Crystal inside of my application  I can actually see a focus box around the cell when a click on it. I am surprised that there is no way to retrieve it through the API.
0
 
LVL 96

Accepted Solution

by:
Bob Learned earned 500 total points
ID: 36815378
Crystal Reports is fairly convoluted, but with a little Reflector magic, you can see how the hit test is used internally.

1) The CrystalReportViewer has a private PageView field.

2) The PageView is a user control that uses a Document instance.

3) The Document references a PageControl instance.

4) The PageControl class has this method:



protected override void OnClick(EventArgs e)
        {
            Point point = this.getCursorPosInClient();
            if (this.page != null)
            {
                SectionInstance instance;
                ReportObjectInstance objectFromPoint;
                PageView parent = (PageView) base.Parent.Parent.Parent;
                TwipPoint position = new TwipPoint(((int) (this.twipsPerPixel * point.X)) - this.pageLeftMargin, ((int) (this.twipsPerPixel * point.Y)) - this.pageTopMargin);
                ReportObjectHitTest.GetSectionAndObjectFromPoint(position, this.page, out instance, out objectFromPoint);
                if (objectFromPoint != null)
                {
                    if (objectFromPoint is SubreportObjectInstance)
                    {
                        this.DrillDownSubReport(instance, objectFromPoint, position);
                    }
                    else
                    {
                        objectFromPoint = ReportObjectHitTest.GetObjectFromPoint(position, this.page);
                        if ((objectFromPoint.HyperLink != null) && (objectFromPoint.HyperLink.Length > 0))
                        {
                            this.RunHyperlink(objectFromPoint.HyperLink);
                        }
                    }
                }
            }
            base.OnClick(e);
        }

Open in new window

0
 

Author Comment

by:aferia
ID: 36816761
Ok. I am trying to get to the PageControl object from the CrystalReportViewer through reflection.
1. I get the "pageView" field. I cant find a "Document" field or property - can you specify where that is coming from?
0
 

Author Comment

by:aferia
ID: 36817240
I dont understand how/where to use the code you have included. Where did you get it from?
How were you able to dig that deep?
0
 

Author Comment

by:aferia
ID: 36817422
I think I have it working now, but I still cant get to the PageControl instance (I need it to calculate the correct TwipPoint position that I will be passing to the  CrystalDecisions.Windows.Forms.ReportObjectHitTest method.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 36817591
If you have Reflector (or something similar like ILSpy), you can load the CrystalDecisions.Windows.Forms assembly, and look at the disassembled code for the library.  The Microsoft.VisualBasic.Compatability library has methods to convert from pixel to twips, and back.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 36817609
Attached are the disasssembled versions of the 4 classes:  CrystalReportViewer, DocumentControl, PageControl, and PageView.



CrystalDecisions.Windows.Forms.zip
0
 

Author Comment

by:aferia
ID: 36817614
WTF - how did you get this? lol
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 36817627
ILSpy:

http://wiki.sharpdevelop.net/ILSpy.ashx

Reflector isn't free anymore, but the free version still works for me.
0
 

Author Comment

by:aferia
ID: 36817628
Nevermind - just read your first comment - thats amazing! Experts-exhange will have to raise the point cap!
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 36817639
Add any tool, like Reflector or ILSpy, that can disassemble a .NET assembly, to your "must-have" list...
0
 

Author Closing Comment

by:aferia
ID: 36817642
This is deep! Thank you so much!
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 36817643
It would be interesting to know if you found a solution or not...BTW
0
 

Author Comment

by:aferia
ID: 36912319
You can get to the pageControl throught the PageView object as follows:

Dim pageControl As CrystalDecisions.Windows.Forms.PageControl = CType(CType(pageView.Controls(0), Windows.Forms.TabControl).SelectedTab, CrystalDecisions.Windows.Forms.DocumentControl).GetPageControl

Open in new window


Then, all you need to do is use the variables described in the code sniped you posted to calculate crystal's mouse position and pass it to the CrystalDecisions.Windows.Forms.ReportObjectHitTest method.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 36912682
Kewl, thank you for sharing!!  *BIG GRIN*
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

861 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question