XamComboBox ComboBoxItemsProvider Very Slow In XamDataGrid

October 25, 2011

I had a page which took 10 seconds to load. When I removed the XamDataGrid Column containing my ComboBoxProvider it took less than 2 seconds to load.

The fix to make it faster was to initialize the ComboBoxProvider through a much faster class. Because ComboBoxProvider is being created once per row, the savings were massive. I also threw away some redundant Binding which cut down on processing time for every DataGridRow.

So I changed this:

igEdit:ComboBoxItemsProvider x:Key="SlowOperationTypeProvider"
ItemsSource="{Binding Source={x:Static enum:EnumDictionary.OperationTypeDictionary}}"
DisplayMemberPath="Key" ValuePath="Value"

To This

igEdit:ComboBoxItemsProvider x:Key="FastOperationTypeProvider"
ItemsSource="{Binding Source={x:Static classlib:Defaults.OperationTypes}}"

EnumDictionary uses Reflection to read a .NET DescriptionAttribute which contains a user-friendly Description for my OperationType Enum. SlowComboBoxItemsProvider iterated through the Enum, used Reflection and Object Casting to create its Dictionary, then used Reflection again to perform DataBinding.

FastComboBoxItemsProvider extracted only the Keys (strings) from an already created EnumDictionary and did not require DisplaymMemberPath or ValueMemberPath attributes. Like I say, I saved 8 seconds in a DataGrid containing only 10 rows.

Advertisements

Entity Framework Type FixupCollection`1 is not marked as serializable.

October 21, 2011

Entity Framework Autogenerated Classes Not Marked as Serializable.

This error comes about while trying to Serialize an EntityFramework Entity that has Associations. I got my error after creating a New entity, saving it, then doing Update on the newly created entity.

A workaround is to add the [Serializable] attribute to the FixUpCollection class, which is located in your .cs file. So, if your EF Template is called StudentEnrolment.tt then FixupCollection is located in StudentEnrolment.cs. Make FixupCollection look like this:

[Serializable]
public class FixupCollection : ObservableCollection

The permanent fix is to modify your Entity Framework template file to make sure that every time your template is run and your Entity classes regenerated then the Serializable attribute is plonked on top of the EF FixupCollection class.

So edit your equivalent StudentEnrolments.tt and find the line where FixupCollection is generated and simply insert the text “[Serializable]” above it, exactly as you would in your class definition, like so:


#>
// An System.Collections.ObjectModel.ObservableCollection that raises
// individual item removal notifications on clear and prevents adding duplicates.
[Serializable]
public class FixupCollection : ObservableCollection
{

All credit to marc_s at Stack Overflow who wrote this and Ross Pace who linked to it from here.

Once again for lovers of Stack Dumps, here’s the full error:

Type 'SubstationLoad.Data.Model.FixupCollection`1[[SubstationLoad.Data.Model.Substation, SubstationLoad.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' in Assembly 'SubstationLoad.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

Adding An Additional Item To A Collection In Entity Framework With Repository Pattern

October 13, 2011

My application has Entities named ‘Hazards’ and ‘Hazard Groups’. A HazardGroup contains many Hazards and the Hazards may be moved from one HazardGroup to another via a Dialog Box.

I found when trying to add an existing Hazard to an existing HazardGroup that I was getting (to paraphrase) ‘Cannot create association: Objects were created in different Data Contexts’ error message. So I needed to put the Hazard and the HazardGroup in the same Object Context.

Here’s how I ended up doing it:

using (var ctx = new HazardContext())
{ {
Hazard movedHazard = _moved hazard returned from my Dialog Box_;
ctx.HazardGroups.Attach(SelectedHazardGroup);
ctx.Hazards.Attach(movedHazard);
SelectedHazardGroup.Hazards.Add(movedHazard);
}

Just to make it spicier I was also using the Repository Pattern, so I had to make sure that my SelectedHazardGroup was attached to the active Repository, like so:

using (var ctx = new HazardContext())
{
IRepository (Of HazardGroup) repo =
new Repository (Of HazardGroup)(ctx);

repo.Attach(SelectedHazardGroup);
Hazard movedHazard = _moved hazard returned from my Dialog Box_;
ctx.Substations.Attach(movedHazard);
SelectedHazardGroup.Hazards.Add(movedHazard);
repo.SaveChanges()
}

HTH.

System.Configuration.ConfigurationErrorsException The Process Was Terminated Due To An Unhandled Exception.

September 26, 2011

We were getting these error in our UAT environment, but not DEV. Betcha you are too.

The reason for this error is that your Config file does not have the structure expected by the .NET runtime. This means that the app. crashes when the Configuration File is accessed.

The particular way in which our config file was malformed was that we were missing the Oracle.DataAccess.Client Section within system.data which was expected because the runtime was trying to load that section due to the presence of a DbProviderConfigurationHandler.

That DbProviderConfigurationHandler was being invoked because we are using Entity Framework connecting to an Oracle Database. EntityFramework was attempting to load various Oracle bits and pieces because the connection string in the app.config within the Visual Studio Class Library Project that connected to the database (i.e. our DAO project) was attempting to load the Oracle DataAccess Provider. This invoked the DbProviderConfigurationHandler but the relevant section in the app.config was not present.

Later on when we manually added the Oracle.DataAccess.Client section we got a crash because the tester’s machine did not have a full installation of Oracle Client for Entity Framework. That’s this sucker.

Now, solving this this was an enormous relief to us because that MinDate setting was being used to dynamically populate an Infragistics ValueConstraint control. When app.config was accessed that control would throw a humungous StaticMarkup Exception. Now this made sense because the ValueConstraint was being populated through a WPF Style but fooled us into thinking that somehow our tester’s machine (running XP) were incompatible with the Infragistics ValueConstraint control. Our DEV machines (running Windows 7) were all fine with the ValueConstraint control.

When we took the ValueConstraint control out (by commenting out the Style) the tester’s machine loaded a cut-down version of our app. fine, but that was only because the cut-down app no longer accessed app.config. Nothing to do with the actual ValueConstraint control at all.

After we removed the ValueConstraints we no longer got StaticMarkup Exception but we did get ConfigurationErrorException and that led us on a Phase 2 Journey Of Pain that, via Divide and Conquer, finally showed us that loading EntityFramework was the REAL real issue.

But not now.

Gloat.

So, bottom line: check that all the Sections expected by your Section Handlers are present. Go back to machine config and see what’s being loaded there and make sure everthing you are expecting to be installed is really installed.

EnterpriseLibrary ExceptionHandlingBlock EventLog Not Written

September 22, 2011

This is a bit of a newb ‘have you tied your shoelaces together’ kind of post, but since I fit the aforementioned category… what the heck…

Yeah, so my EventLogs were getting written, then later on they weren’t getting written, so what changed ?

Well I sat down and picked carefully through my app.config using the Enterprise Library Configuration Tool trying to see whether or not all the bits were connected properly. And what I think I saw was that the Logging Category of my Logging Exception Handler was set to ‘General’ but that under ‘Logging Settings’ the ‘General’ category did not have the Event Log Trace Listener added to it.

So I added ‘EventLogTraceListener’ to ‘General’ and simultaneously removed it from another category,’Logging Errors And Warnings’.

Except nothing happened…still no EventLog.

Except that when I closed my hosting app again and reopened the Configuration manager again and generally opened and closed the car doors in a futile attempt to make something change… it suddenly worked.

So Partial Huzzah (PHUZ)!. Nah, bugger it: HUZZAH!

That feels better.

ObjectDisposedException EntityFramework

September 21, 2011

I had a using clause around my call to Entity Framework like so:

using (var ctx = new SubstationLoadContext())
{
IRepository repo =
new Repository(ctx);

AreaSummations = repo.GetAreaSummationsWithEquipmentWithReadingUnits();
}

Subsequently while performing a LINQ query on AreaSummations I received the fiendish ObjectDisposedException. Porquoi ?

Some quick Googling told me that since my context variable was being disposed before I performed the query I should force the creation of an in-memory List in order to detach from the database i.e. I should do a .ToList() like so:

AreaSummations = repo.GetAreaSummationsWithEquipmentWithReadingUnits.ToList();

But my repo method was already doing a .ToList(). I was already detached from the database wasn’t I? Nyet.

The Botswanian Programming Legend masquerading as Mark Gravell on Stack Overflow informed me that the issue was that EF was lazily-loading some portion of the object graph and I needed to force an eager load by use of Entity Framework .Include. HUZZAH!

But I was already forcing an eager load wasn’t I ? See…

summations = (from s in ((SubstationLoadContext)repo.Context)
.SubstationGroupSummationTypes
.Include("Equipments.EquipmentReadingUnits")

Mais Non! I was NOT forcing an eager load because I had improperly specified the path to EquipmentReadingUnits. I had only included the path from about half-way up the object graph I needed to include the full path from the root Entity. Like so:
summations = (from s in ((SubstationLoadContext)repo.Context)
.SubstationGroupSummationTypes
.Include("SubstationGroup.Substations.Equipments.EquipmentReadingUnits")

PROPER HUZZAH! The eager load was correctly specified and ObjectDisposedException was banished!

Moral of the Story:

When getting ObjectDisposedException with Entity Framework make sure you have correctly specified the path for your eager loads. And include them if they are not already present. And then you will no longer see this

System.ObjectDisposedException: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection

Locating DataContext Of Infragistics WPF ContentPane from the ContentPaneTabHeader

September 19, 2011

Dammit, I forgot the juicy parts of how I went about resolving this particular Jouney Of Pain, but the answer is: to locate the DataContext of the ContentPane from the ContentPane TabHeader you must navigate to the PaneTabItem and descend through two DataContexts.

Here’s one of me doing the above, Binding the Fill Property of a Rectangle to a Property on the ContentPane. (Yes, this does assist World Peace).

Fill="{Binding Path=DataContext.DataContext.whatever,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type igDock:PaneTabItem}}}"

System.Windows.Markup.XamlParseException when starting WPF Application

September 13, 2011

In all likelihood you have forgotten to bundle a third-party dll with your deployment.

In my case I had neglected to set “Copy To Local” to true for the dlls from the Infragistics control set. Because they were installed on the GAC in my DEV machine the deployment bundle ran fine on DEV but they were not in the GAC on TEST hence the crash.

So make sure all your third party dlls are deployed.

For Lovers Of Stack Traces, here’s the whole horror show, excised from the Windows Event Log. Enjoy(ish)

Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Windows.Markup.XamlParseException
Stack:
at System.Windows.Markup.XamlReader.RewrapException(System.Exception, System.Xaml.IXamlLineInfo, System.Uri)
at System.Windows.Markup.WpfXamlLoader.Load(System.Xaml.XamlReader, System.Xaml.IXamlObjectWriterFactory, Boolean, System.Object, System.Xaml.XamlObjectWriterSettings, System.Uri)
at System.Windows.Markup.WpfXamlLoader.LoadBaml(System.Xaml.XamlReader, Boolean, System.Object, System.Xaml.Permissions.XamlAccessLevel, System.Uri)
at System.Windows.Markup.XamlReader.LoadBaml(System.IO.Stream, System.Windows.Markup.ParserContext, System.Object, Boolean)
at System.Windows.Application.LoadBamlStreamWithSyncInfo(System.IO.Stream, System.Windows.Markup.ParserContext)
at System.Windows.Application.LoadComponent(System.Uri, Boolean)
at System.Windows.Application.DoStartup()
at System.Windows.Application.b__1(System.Object)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(System.Object)
at System.Threading.ExecutionContext.runTryCode(System.Object)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode, CleanupCode, System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
at MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
at System.Windows.Threading.Dispatcher.InvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef)
at System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame)
at System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame)
at System.Windows.Threading.Dispatcher.Run()
at System.Windows.Application.RunDispatcher(System.Object)
at System.Windows.Application.RunInternal(System.Windows.Window)
at System.Windows.Application.Run(System.Windows.Window)
at System.Windows.Application.Run()
at SubstationLoad.App.Main()

Watermark in Filter Row of XamDataGrid

September 7, 2011

This one took some avid Googling and a lucky guess.

To put a Watermark in the Filter Row of a XamDataGrid from Infragistics you need to create a new FilterCellEditorStyle for the XamComboBox which is the editor control in that filter row.

All kudos to Alex Fidanov of Infragistics support who, in this Infragistics Community Thread, “How to show empty string as DisplayText instead of value when value is not found in combo’s ItemsSource”, gave the basic answer.

The basic idea is to swap the Watermark in and out as a complete piece of Content for the XamComboBox, that content replacing the XamCombo’s usual Content.

Here’s WatermarkComboEditorStyle:

Style x:Key="WatermarkComboEditorStyle" TargetType="{x:Type igEdit:XamComboEditor}"
Setter Property="Template"
Setter.Value
ControlTemplate TargetType="{x:Type igEdit:XamComboEditor}"
Border x:Name="MainBorder" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Grid
Grid.ColumnDefinitions
ColumnDefinition Width="*"/
ColumnDefinition Width="Auto"/
/Grid.ColumnDefinitions
Grid.RowDefinitions
RowDefinition/
/Grid.RowDefinitions
Border Grid.Column="0" Margin="1,0,0,0" Padding="{TemplateBinding Padding}"
Grid
ContentPresenter x:Name="PART_Content"
Content="{Binding DisplayValue, ConverterParameter='', Mode=OneWay,
RelativeSource={RelativeSource TemplatedParent}}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/
!-- This text box is the actual watermark --
TextBlock x:Name="PART_NullText"
Text="Watermark Text" Visibility="Collapsed" FontStyle="Italic"
Foreground="Gray" FontWeight="Bold" /
/Grid
/Border
ToggleButton x:Name="PART_DropDownButton" ClickMode="Press" Grid.Column="1" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, UpdateSourceTrigger=PropertyChanged}" Style="{TemplateBinding DropDownButtonStyle}" Visibility="{TemplateBinding DropDownButtonVisibility}" /
/Grid
/Border
ControlTemplate.Triggers
Trigger Property="IsEnabled" Value="True"
Setter Property="Visibility" TargetName="PART_DropDownButton" Value="Visible"/
Setter Property="Visibility" Value="Visible" TargetName="PART_NullText"/
Setter Property="Content" Value="" TargetName="PART_Content"/
/Trigger

/ControlTemplate.Triggers
/ControlTemplate
/Setter.Value
/Setter
/Style

Once you have created the Style, assign it to FilterCellEditorStyle in the FieldSettings for the Datagrid like so:

Style x:Key="XamDataGridFiltered" TargetType="{x:Type igdp:XamDataGrid}"
BasedOn="{StaticResource XamReadOnlyDataGrid}"
Setter Property="FieldSettings"
Setter.Value
igdp:FieldSettings AllowRecordFiltering="True" FilterCellEditorStyle="{StaticResource WatermarkComboEditor}"
/igdp:FieldSettings
/Setter.Value
/Setter
/Style

Alex is now awarded the title of Slavic Programming Legend. Congrats Alex.

Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler Cannot Be Resolved

August 30, 2011

Having got the error in the title you may also have noticed
EnterpriseLibraryContainer.Current throws an ArgumentException.

The reason for this is that you are missing a reference to the ExceptionHandler.Logging dll
i.e. Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.dll

…And/Or you have not copied that dll to the bin directory of your solution.

You wouldn’t forget something as simple as that, would you ?

I certainly didn’t.
And neither did NORBERT my invisible Aardvark snowboarding companion.

And that full error text for your unmitigated reading pleasure:

‘Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’ cannot be resolved. Please verify the spelling is correct or that the full type name is provided.