Exceptions

Jul 7, 2010 at 3:59 PM
Edited Jul 7, 2010 at 4:04 PM

I have created a simple RibbonWindow using the tutorial that is included and it worked beautifully. However, when I try to get the ribbon on my app I am having some problems. In Visual Studio it looks fine and compiles but when I try to open a RibbonWindow with nothing on I get a NullReferenceException. Here is part of the stack trace...

System.NullReferenceException
   at Fluent.RibbonWindow.OnCoerceStyle(DependencyObject d, Object basevalue) in C:\Users\Sergey\Documents\Visual Studio 2008\Projects\Fluent\Fluent\RibbonWindow.cs:line 309

   at System.Windows.DependencyObject.ProcessCoerceValue(DependencyProperty dp, PropertyMetadata metadata, EntryIndex& entryIndex, Int32& targetIndex, EffectiveValueEntry& newEntry, EffectiveValueEntry& oldEntry, Object& oldValue, Object baseValue, Object controlValue, CoerceValueCallback coerceValueCallback, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, Boolean skipBaseValueChecks)

   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)


If, instead I add the reference to the library I get a different NullReferenceException....

An unexpected error has occurred:  Object reference not set to an instance of an object.

System.NullReferenceException
   at Fluent.IconConverter.System.Windows.Data.IValueConverter.Convert(Object value, Type targetType, Object parameter, CultureInfo culture) in C:\Users\Sergey\Documents\Visual Studio 2008\Projects\Fluent\Fluent\IconConverter.cs:line 34

   at System.Windows.Data.BindingExpression.TransferValue(Object newValue, Boolean isASubPropertyChange)

   at System.Windows.Data.BindingExpression.Activate(Object item)

   at System.Windows.Data.BindingExpression.AttachToContext(AttachAttempt attempt)

   at System.Windows.Data.BindingExpression.AttachOverride(DependencyObject target, DependencyProperty dp)

   at System.Windows.Data.BindingExpressionBase.Attach(DependencyObject target, DependencyProperty dp)

   at System.Windows.Data.BindingExpressionBase.OnAttach(DependencyObject d, DependencyProperty dp)

If I add a simple ribbon like this...

<Fluent:RibbonWindow
    x:Class="Jet.Framework.DataSourceSettingsWindow.DataSourceSettingsWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:Fluent="clr-namespace:Fluent;assembly=Fluent"
  mc:Ignorable="d"
    Title="Data Source Settings"
  Height="460"
    Width="600"
    Background="WhiteSmoke">
    <Window.Resources>
        <ResourceDictionary Source="pack://application:,,,/Fluent;Component/Themes/Office2010/Silver.xaml" />

   </Window.Resources>
<Grid Grid.Row="0">
                <Fluent:Ribbon>
                    <Fluent:RibbonTabItem Header="Data Sources">
                        <Fluent:RibbonGroupBox Header="">
                            <Fluent:Button Name="buttonGreen" Text="Test Connection"/>
                            <Fluent:Button Name="buttonGray" Text="Set Default"/>
                        </Fluent:RibbonGroupBox>
                    </Fluent:RibbonTabItem>
                </Fluent:Ribbon>

            </Grid>I get a TargetInvocationException. Here is part of the stack trace...
</Fluent:RibbonWindow>

An unexpected error has occurred:  Exception has been thrown by the target of an invocation.

System.Reflection.TargetInvocationException
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)

   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache)

   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache)

   at System.Activator.CreateInstance(Type type, Boolean nonPublic)



I must have missed something, any ideas you have would be helpful. Again, it all works in Visual Studio which is the frustrating part.

 

Jul 7, 2010 at 11:43 PM

The error is not in your XAML. I was able to cut and paste your code and create a RibbonWindow without any problem.

Are you changing values in your .CS that could be causing the problem?

If so, you should added a Loaded event to your XAML and in the code behind, set any of your values there. This will ensure that the Ribbon has been fully created and available to be modified (i.e. no values are NULL)

 

Jul 8, 2010 at 6:57 PM
No, the only code I have is the default constructor with InitializeComponent(). The window is in a project that is a class library and opened by a parent application. I have a feeling that this is what the issue is.
Jul 10, 2010 at 12:14 AM

I believe you may be experiencing the same issue I was having.  See Discussion List: 

SOLUTION FOUND: SHOW STOPPER: Windows application cannot call the RibbonWindow - Error
The error we had was also in the module OnCoerceStyle in RibbonWindow.cs and RibbonTabItem.cs.  
What we found was that if you load the ResourceDictionary from Application.xaml, calling the Window directly did not load the Resource.  
So when Fluent.RibbonWindow.OnCoerceStyle was called it could not locate the resource and the Exception was thrown.  
Alternatively, you load the ResourceDictionary in the Window.xaml, but the resource is available after InitializeComponent() is called, also resulting in the Exception.
If you add the ResourceDictionary as we did in the last post, it solves the problem.  
The ResourceDictionary is available before InitializeComponent() is called and OnCoerceStyle completes successfully.
Hope this helps.
Jul 12, 2010 at 4:01 PM
Thanks for your reply KristiL, that was in fact my issue. Will this be fixed in the next build?
Jul 12, 2010 at 5:42 PM

I found one issue with this solution. If your ribbonwindow is going to be reopened multiple times you'll need to change the shutdown mode of the app that is created in EnsureApplicationResources() like so...

		private void EnsureApplicationResources()
		{
			if (Application.Current == null)
			{
				new Application() { ShutdownMode = ShutdownMode.OnExplicitShutdown };
				Application.Current.Resources.MergedDictionaries.Add(Application.LoadComponent(new Uri("/Fluent;Component/Themes/Office2010/Silver.xaml",
					UriKind.RelativeOrAbsolute)) as System.Windows.ResourceDictionary);
			}
		}

 

Jul 12, 2010 at 5:44 PM

daVinci (moderator) moved the discussion item to an issue.  I don't know how they evaluate or plan to release fixes, but I hope it is soon. 

The one additional thing you need to do if you use the work around is to add:

Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose;
To the Window_Closing event.  This will release the manual call to load the application level and dispose of the object.  
If you don't do this, you can't call the window a second time.
Jul 12, 2010 at 5:44 PM

Or your solution works as well.  Kristi