2014-07-25

[SOLVED] GrapeCity/ComponentOne ActiveReports 8 - Excel Export using WebViewer is broken

The ActiveReports engine is a great engine for rendering reports for an application.  Sometimes, though, errors will occur that have multiple reasons for why they show up; some known, others not.

It's very hard to troubleshoot those or to find solutions for them, even if you have incredible internet search skills.  That said, this solution may not work for you, but hopefully will give you a quick test to see if you can move on to another suggestion.

I was puzzled while trying to solve a problem we had in our web application where exporting via ActiveReports 8 WebViewer to PDF or DOC worked fine, but XLS for some reason returned a 404 error.

The problem turned out to be with mine that we missed laying down a DLL required by the Excel exporter (GrapeCity.ActiveReports.Export.Excel.v8.dll) called DocumentFormat.OpenXml.dll, which didn't seem to be referenced by the other Export DLLs.  

As soon as I put this in place, it started working again.

This file could be easily missed as it is not named like the other export related DLLs:
GrapeCity.ActiveReports.Export.*.v8.dll

Make sure to include that and you'll have one less reason to see a 404 error when you try exporting to Excel from ActiveReports!

On a side note, the following are all of the referenced DLLs (Microsoft DLLs excluded) for GrapeCity.ActiveReports.Export.Excel.dll in case you need to check for others also missing:
  • DocumentFormat.OpenXml.dll
  • GrapeCity.ActiveReports.Diagnostics.v8.dll
  • GrapeCity.ActiveReports.Document.v8.dll
  • GrapeCity.ActiveReports.Export.Rdf.v8.dll
  • GrapeCity.ActiveReports.Extensibility.v8.dll
  • GrapeCity.ActiveReports.v8.dll
Best of luck!

2013-08-28

MSBuild - Copy Task using Items with Includes and Excludes

I struggled for a couple of hours on this one... until finally finding this useful answer from stackoverflow.com! My scenario was needing to copy some files in a pre-build step in a Visual Studio C# project. For every file I needed to copy, there was a counterpart for each of our supported languages. The naming convention for the files was like this:

MyFile.properties
MyFile_de_DE.properties
MyFile_fr_FR.properties

etc.

Here is what my csproj looked like:
<PropertyGroup>
    <ReportingEnglishLocFolder>$(SolutionDir)..\path\to\destination\</ReportingEnglishLocFolder>
</PropertyGroup>
<ItemGroup>
    <EnglishLocPropertiesFiles
        Include="$(ReportingBaseFolder)master\*.properties"
        Exclude="*_de_DE.properties"/>
</ItemGroup>
<Copy
        SourceFiles="@(EnglishLocPropertiesFiles)"
        DestinationFolder="$(ReportingEnglishLocFolder)" />

After attempting multiple combinations of wildcard patterns and having no success, I changed the search phrases I used to search the internet and found the stackoverflow thread.
The most important part from the thread, and the most important thing to remember about using Include and Exclude is:
If you use an absolute path for Include, you must use an absolute path for Exclude. If you use a relative path for Include, you must use a relative path for both.
So I changed to this and it worked like a champ!
<ItemGroup>
    <EnglishLocPropertiesFiles
        Include="$(ReportingBaseFolder)master\*.properties"
        Exclude="$(ReportingBaseFolder)master\*_de_DE.properties"/>
</ItemGroup>

So remember, whichever type of path you use for Include, you need to do the same for Exclude.

2013-08-09

Silverlight: ObservableCollection.CollectionChanged Event

The ObservableCollection<T>.CollectionChanged event will only fire if the collection itself changes (items are added, removed or rearranged/moved.), NOT if an item in the collection changes (meaning one of the item's in the collection has one or more properties modified.)

It's now around 2:30am, and I've been going the rounds for a couple of hours with a Silverlight project at work; fighting a seemingly simple change that ended up not being so simple because of a major misunderstanding of the CollectionChanged event on the ObservableCollection<T>.  My ObservableCollection<T>.CollectionChanged event was not firing like I thought it should.

I imagine this will be a common mistake for others, and I'm sure I myself am doomed to repeat it again in the future; so I'm documenting it for a quick reminder later.

My thought process was this... "I need to watch my ObservableCollection for one of its items to be changed.  Once the item is changed, I need to flip a boolean flag which happens to be bound to a command which will disable a button after the change has been made."

Simple, right?
I should just be able to handle the ObservableCollection<T>.CollectionChanged event, because if one of those items in the collection gets changed, that counts... 

Or not.

See, the misconception is, the collection itself hasn't changed.  It has the exact same items it had before, it's just that the item within the collection changed.  So there are two things that can happen to your collection:

  • The collection itself is modified (Items are added, removed or moved.)
  • An item in the collection is modified (its individual properties are changed.)

Let me illustrate:
For this example we will have a class called VideoGame to keep track of titles and costs.

public class VideoGame : INotifyPropertyChanged
{
 private string _title;
 public string Title 
 { 
  get { return _title; } 
  set
  {
   _title = value;
   RaisePropertyChanged("Title");
  }
 }
 
 private decimal _cost;
 public decimal Cost 
 { 
  get { return _cost; } 
  set
  {
   _cost = value;
   RaisePropertyChanged("Cost");
  }
 }
 
 public event PropertyChangedEventHandler PropertyChanged;
 public void RaisePropertyChanged(string propertyName)
 {
  if(PropertyChanged != null)
   PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
 }
}

And now some code to use it...

ObservableCollection<VideoGame> videoGames = new ObservableCollection<VideoGame>
{
 new VideoGame{ Title = "TrackMania 2: Stadium", Cost = 9.99M },
 new VideoGame{ Title = "TrackMania 2: Canyon", Cost = 19.99M },
 new VideoGame{ Title = "TrackMania 2: Valley", Cost = 19.99M },
};

videoGames.CollectionChanged += (sender, eventArgs) => {
 
 Debug.WriteLine("--- The collection changed");
};

Debug.WriteLine("Changing the cost of one of the video games in the collection...");
// The CollectionChanged event will not fire because it was just one of the collection's items that changed...
// not the collection itself.
videoGames[0].Cost = 7.99M; // the game went on sale.

Debug.WriteLine("Adding a video game to the collection...");
// The CollectionChanged event WILL fire because the collection of items changed.
videoGames.Add(new VideoGame{ Title ="ShootMania: Storm", Cost = 19.99M });

And the output...
Changing the cost of one of the video games in the collection...
Adding a video game to the collection...
--- The collection changed
When it dawned on me, at first I was frustrated; but then clarity set in.  It makes sense to me that we only want the CollectionChanged event to fire when the collection itself is modified, not its individual parts.  With it, the NotifyCollectionChangedEventArgs that are passed with the event give us a lot of good information about what happened with the change.

  • Action - Tells which action effected the change in the collection (Add, Remove, Replace, Reset)
  • NewItems - The items affected by the action
  • OldItems - The items removed or replaced in the collection
  • NewStartingIndex - Tells the index where the change occurred.
  • OldStartingIndex - Tells where a Replace or Remove action took place.
While all this is cool, what do I need to have happen so I can track when an item in the collection is changed?

I need to make sure I handle PropertyChanged on the individual items of the collection.  Make note, this can be tricky because I still need to watch for the Collection to change so I can subscribe to any new items' PropertyChanged events as they are added to the collection, and clean up after myself when the items leave the collection.

I'll let you decide how you're going to approach that; it's a discussion for another day.  But I want to drive home the concept that the CollectionChanged event is just that... when the collection itself changes, not its individual items.  Know that, and you'll save yourself a lot of time.

2013-04-02

[SOLVED] "Attaching the Script debugger to process iexplore.exe failed" message after upgrading to Internet Explorer 10

HUGE thanks going out to Dmitri Leonov - MSFT in a stackoverflow article about the same message.
After updating to Internet Explorer 10, I started receiving the error when debugging with Visual Studio 2010:

"Attaching the Script debugger to process [####] iexplore.exe failed.  Another debugger may already be attached to the process."

The fix:

  • Close all instances of Internet Explorer.  (I will add you can leave Visual Studio open)
  • Run a command prompt as Administrator and paste this little gem into the command line:

 
It worked like a champ for me (and apparently others from comments on the stackoverflow post.)

Good riddance to an annoying message!  Happy coding.

2013-01-08

JavaScript String.Replace: Replacement Pattern for Full Match Reminder

This is my quick reminder to self to use
$&
instead of
$0
in JavaScript for Regular Expression replacement patterns when wishing to use the entire matched text.

Some browsers allow $0, but $& is officially documented (table 22, page 147) and supposed to work in all of them.

Example:
document.write("Hello World".replace(/^Hello/, "$& to the whole");

Output:
Hello to the whole World

2012-09-29

LINQ to Objects: Querying Nested Collections

I love LINQ.  LINQ is just fun to use.  I love the fact that I can query the same way across databases, XML  documents and objects (alright XML is slightly different, but...)

Today I had the task of querying down a complex set of objects that each own a collection data member.  I needed to get to some data 4-layers deep and thought the LINQ query would get pretty nasty.  That is until I learned that I can use the "from" keyword multiple times in the same LINQ query.

My example will be very contrived to save having to look at a lot of extra code for different collections, so I'll go ahead and just nest the same collection several layers down, just so we get the concept.

I have a Person class:
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    private List<Person> _children;
    public List<Person> Children 
    {
        get{ return _children ?? (_children = new List()); } 
        set{ _children = value; }
    }
}
If I set up a new List<Person> like so:
  List<Person> grandpas = new List<Person>
  {
    new Person{
      FirstName = "John", LastName = "Doe", IQ = 91,
      Children = new List<Person>{ // children
        new Person{ FirstName = "Meh", LastName = "Doe", IQ = 103 },
        new Person{
          FirstName = "Tae Kwon", LastName = "Doe", IQ = 125,
          Children = new List<Person>{ // grandchildren
            new Person{ FirstName = "Karate", LastName = "Kid", IQ = 68, },
            new Person{ FirstName = "Karate", LastName = "Kid2", IQ = 117 },
          }
        },
      }
    },
 
    new Person{
      FirstName = "John", LastName = "Doh", IQ = 135,
      Children = new List<Person>{ // children
        new Person{ FirstName = "Meh", LastName = "Doh", IQ = 42 },
        new Person{
          FirstName = "Tae Kwon", LastName = "Doh", IQ = 140,
          Children = new List<Person>{ // grandchildren
            new Person{ FirstName = "Doh", LastName = "Boy", IQ = 111 },
            new Person{ FirstName = "Doh", LastName = "Nut", IQ = 98 },
          }
        },
      }
    },
  };
Check out how easy it is to get to data that is below the top layer:
IEnumerable<Person> grandChildrenWithHighIQ = from grandpa in grandpas from parent in grandpa.Children from grandkid in parent.Children where grandkid.IQ > 100 select grandkid;
Now we know longer need be afraid of querying complex objects and getting the data we want.  Write your queries in the bLINQ of an eye, and get your data back even faster!

And I'll put a shameless plug out there for LINQPad since I took a screenshot from its results above.  It is a fantastic tool for crafting LINQ queries and is a wonderful sandbox for small .NET proof-of-concept projects because you can write small programs without creating a Visual Studio project or solution.

Enjoy!

2012-08-29

Telerik RadNumericUpDown for Silverlight does not update binding when value is blanked out

Note: This may be fixed in a later version of Telerik controls; this issue was discovered in the Telerik.Windows.Controls library; version 2011.1.315.1040

Working on a Silverlight application, we found ourselves with some dialogs that utilize the Telerik RadNumericUpDown control.  We discovered a defect when binding the Value property of the control to a ViewModel behind the scenes.

The original binding works as expected, and if the spinner controls are used to change the value, the ViewModel updates as we expect.  If a user types a new value into the control it also updated the binding on the ViewModel correctly.

The problem arises when we blank out the value by clicking into the textbox portion of the control, highlighting it and hitting the Backspace or Delete key.  Removing focus from the control or not, the ViewModel property bound to that control does not get updated.

To work around this, we created this Event Handler:
void RadNumericUpDown_ValueChanged(object sender, 
                                   RadRangeBaseValueChangedEventArgs e)
{
    if (sender is RadNumericUpDown)
    {
        RadNumericUpDown upDownControl = sender as RadNumericUpDown;
        if (!upDownControl.Value.HasValue)
            upDownControl.Value = upDownControl.Minimum;
    }
}
Now we apply this event handler to our XAML:
<telerik:RadNumericUpDown ValueChanged="RadNumericUpDown_ValueChanged" ... />
This makes the behavior act the same as if the user had used the down spinner on the control to modify the value down to the minimum.

This may not be the ideal solution for you, but understanding this will give you direction on how you can create your own workaround.  We started down the path of handling the KeyUp event, but ValueChanged seems much more appropriate.

Telerik makes fantastic controls; and I'm not mad by any means.  Being a developer myself, I realize these things happen; but I do hope they have handled this better in a later release.  And as far as I know this is the only control in the 2011.1.315.1040 version that has this issue.

2012-07-04

PayPal Instant Payment Notification (IPN) Simulator Requires Port 80

Someone please correct me if I'm wrong, but I fought for an hour or more trying to get PayPal's Instant Payment Notification (IPN) Simulator to post test transactions to my test site running on IIS Express which listens on a port different than 80; and it just doesn't work.

I asked friends on external networks to bring my site up in their browsers and they could hit it fine on the non-standard port, so I knew my firewall and IIS Express were configured correctly.

I cannot find anywhere in PayPal's documentation where it states that port 80 is required but it seems their own firewall is pretty strict with outbound traffic.  Once I forced my router to listen on port 80, and forward the request to the non-standard port my site listens on, the simulator worked like a champ.

So, if you're having problems with the IPN simulator not sending to your listener and you are listening on a non-standard port, make sure to do one of the following:

  1. Force your test site to listen on port 80 and configure your firewall accordingly.
  2. Force your router to listen on port 80, but forward to the port your test site is set up on.
That's what we like to see!
As a side note, if I remember correctly... the standard ASP.NET Development Server (Cassini) that comes with Visual Studio, does not accept requests from an external network.  I believe it can only accept them from the same machine you are doing the development on.  This is why I opted to use IIS Express.

Hope this saves someone else some time and head-banging on your desk.  :)
Happy coding!

2011-11-02

Silverlight Unit Testing: TestInitialize/TestCleanup methods do not fire, tests do not run, nor pass/fail, and no details given

I had the classic bang-head-against-the-keyboard for three hours scenario today while doing Silverlight Unit Testing.

I had a test class with two unit tests in them which worked fine, until I started refactoring to get common setup/teardown functionality moved into methods with TestInitialize/TestCleanup attributes applied.

Then the weirdness started.  I started seeing this:
The tests don't run; don't pass or fail; and no details as to why.
Check out the yellow highlighted areas.
As you can see, there wasn't a whole lot of information present to assist me in my predicament.  After removing the TestInitialize/TestCleanup attributes, the tests worked fine.

I began searching the internet trying to find someone who ran into the same problem.  I found many results where developers complained of the TestInitialize methods swallowing exceptions and moving on, so I started down that path in my own code, trying to discover if there was an exception I was missing that was being eaten and causing the entire class to fail.

The only problem was, when I commented all code within the bodies of the TestInitialize/TestCleanup methods, I still ended up with the same results.
???
Digging deeper, it finally dawned on me that the test class in question was inheriting from a base test class that also happened to have methods dressed with the TestInitialize/TestCleanup attributes.  Looking at the declaration of TestInitializeAttribute revealed what I suspected:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public sealed class TestInitializeAttribute : Attribute

AllowMultiple = false... which makes sense. So my code had two problems:

  1. My base class' method for TestInitialize needed to be made virtual so it could be overridden in classes that inherit from it to allow for overriding (and calling back to the base so both get their jobs done.)
  2. My child class' method was named different, so I needed to go make it match and override.
Once I fixed these problems for both the init and cleanup methods, the tests went back to working accurately.

Bottom Line: When doing unit testing with base test classes that perform common setup functionality, make sure to have your Setup/Teardown or Initialize/Cleanup methods marked virtual in the base class, so they can be overridden in the sub-classes.  Then override those methods in the sub-class, making sure to call back to the base appropriately.

Example (MSTest):

public class CommonTestSetupBase { [TestInitialize] public virtual void TestSetup() { // do common setup work for all that inherit } [TestCleanup] public virtual void TestTeardown() { // do common cleanup work for all that inherit } } //================= [TestClass] public class UnitTestedClassTests : CommonTestSetupBase { [TestInitialize] public override void TestSetup() { base.TestSetup(); // do common setup for this class } [TestCleanup] public override void TestTeardown() { // do common cleanup for this class base.TestTeardown(); } } I knew I wouldn't remember this if I bump into it again, so I had to document it here... I wish I had more time to go into more detail, but I hope this will be enough to help you and I in the future when we meet this problem again.

2011-08-30

Silverlight throws InvalidOperationException with Common_MethodFailed error when calling HtmlElement.SetAttribute for the "type" attribute

I was working on a Silverlight application the other day and needed to create and submit an HTML form to another ASPX page inside the website hosting the app.

To accomplish this, I was using the HtmlDocument.CreateElement, HtmlElement.SetAttribute and HtmlElement.AppendChild methods to set the whole thing up.

After deploying the application having success with Internet Explorer 9 (IE9), Chrome, etc. we tested on two virtual machines that had IE7 and IE8 and were met with errors and no form submission.

It turns out it was because I was trying to set the "type" attribute of the <input /> elements I was creating with the Silverlight methods after I'd called the AppendChild method.

IE7 and IE8 don't like a developer setting the "type" attribute after the element has been appended to the document and it will throw a JavaScript error which bubbles up to the Silverlight application and the user is shown an obscure InvalidOperationException error whose key is "Common_MethodFailed".

It made no sense to me, but I dug deeper until I could find the offending line.  I then tried an experiment with a XHTML/JavaScript page in the offending browsers to see if it was a Silverlight problem or a problem with the JavaScript engines of said browsers.

I ran into the same problem without Silverlight in the equation.  I wrote up a detailed article explaining it and have the experiment to try in different browsers yourself on my JavaScript Jedi website.

The problem can be solved by making sure you call AppendChild AFTER you set up all the properties/attributes on the HtmlElement, not before.

I hope this helps you avoid several hours of frustration.  :)
Happy Coding!