xceedsoftware / wpftoolkit

All the controls missing in WPF. Over 1 million downloads.
Other
3.9k stars 877 forks source link

NullReferenceException in LayoutAnchorableFloatingWindowControl.OnInitialized #1442

Open meyerrn opened 5 years ago

meyerrn commented 5 years ago

Hello, I migrated from 3.3 to 3.5, but now the application does not start anymore. Crash while loading (Deserialize) a layout. See Stack trace below. "_model" is null. I think initialization is missing in constructor LayoutAnchorableFloatingWindowControl( LayoutAnchorableFloatingWindow model)

I skipped 3.4 because of another serious error.

System.NullReferenceException HResult=0x80004003 Message=Object reference not set to an instance of an object. Source=Xceed.Wpf.AvalonDock StackTrace: at Xceed.Wpf.AvalonDock.Controls.LayoutAnchorableFloatingWindowControl.OnInitialized(EventArgs e) at System.Windows.FrameworkElement.TryFireInitialized() at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args) at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType) at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal) at System.Windows.PresentationSource.RootChanged(Visual oldRoot, Visual newRoot) at System.Windows.Interop.HwndSource.set_RootVisualInternal(Visual value) at System.Windows.Window.SetRootVisual() at System.Windows.Window.SetRootVisualAndUpdateSTC() at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight) at System.Windows.Window.CreateSourceWindow(Boolean duringShow) at System.Windows.Window.ShowHelper(Object booleanBox) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.DispatcherOperation.InvokeImpl() at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state) at System.Windows.Threading.DispatcherOperation.Invoke() at System.Windows.Threading.Dispatcher.ProcessQueue() at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) at System.Windows.Application.RunDispatcher(Object ignore) at System.Windows.Application.RunInternal(Window window) at MyApp.App.Main()

jmtuset commented 5 years ago

I found the same problem.

I make a litlle change in the constructor to hotfix. Change base -> this

internal LayoutDocumentFloatingWindowControl( LayoutDocumentFloatingWindow model ) :this( model, false ) { }

Dirkster99 commented 5 years ago

It turns out that version 3.5 has the same critical issue in 2 different classes. The issue with the NullReference Exception shows when

The correct fixes (see both references above) contain more than just setting the _model field since you are otherwise reloading a tool window layout without the abbility to close it later on (since the CloseCommand is not initialized if any of the fixes suggest here or there is applied).

guy-avery commented 5 years ago

@Dirkster99 - I think your statement is correct,

The correct fixes (see both references above) contain more than just setting the _model field since you are otherwise reloading a tool window layout without the abbility to close it later on (since the CloseCommand is not initialized if any of the fixes suggest here or there is applied).

But @jmtuset has the correct solution - you just need to call the other constructor - which will re-use the required initialisation code. Copying the same code between constructors in the same class is not good practice and usually indicates something is wrong with the design.

Hopefully the correct solution will be adopted but unless you have a very good reason not to, I would recommend you update your solution to represent @jmtuset's solution.

Dirkster99 commented 5 years ago

@guy-avery Thanks for pointing this out to me. You are right. The issue is in both cases the same and it can be solved with the same resolution as suggested by @jmtuset I've commit the correct solution and will it roll out to NuGet/Release Version with the next bug fix :-)

guy-avery commented 5 years ago

@Dirkster99 - that's great - thanks for the response.

XceedBoucherS commented 5 years ago

Hi, This is already fixed in v3.6 (the next community edition to be released). You can already try the latest v3.8 version for free for 45 days here : https://xceed.com/xceed-toolkit-plus-for-wpf/

junrau commented 5 years ago

Since this is a significant issue, can you re-list 3.4 on NuGet, so we can revert until the fixed code is released?

sa-he commented 5 years ago

Can't you please just create a release 3.5.1 or something, that includes this bugfix?

Dirkster99 commented 5 years ago

I have created a version with a fix (and now you know why): https://github.com/Dirkster99/AvalonDock

sa-he commented 5 years ago

Great @Dirkster99 , do you also publish nuget packages for your repo?

Dirkster99 commented 5 years ago

Yes, just click on one of the buttons in the Readme.md page:

Untitled

...and you shall see the nuget package belonging to it:

So, clicking on the first button (left cell from) AvalonDock should, for example, get you here: https://www.nuget.org/packages/Dirkster.AvalonDock

Also, be sure to scroll down the Readme.md to check out the list of other critical issues that have already been fixed in this release. And there is also a Wiki page link at the bottom of the page that gives you a list of fixes that have been fixed in previous release (should you need any before 3.5).

Its still surprising to me how these discussions come back time and again. And yet, xceed claims to maintain the open source release and people actually expect their problem to be fixed in a smaller time spane than 2 years ...

sa-he commented 5 years ago

Great job @Dirkster99 ! How can I use other usercontrols of the wpftoolkit and your version of AvalonDock at the same time? Do you have a different xml namespace to import?

Dirkster99 commented 5 years ago

I am not sure how to answer this one as I am not in that situation and I did not change any namespaces since this would break existing applications for all other users (including myself).

But one way I could imagine for using this mixed setup of:

would be to download both packages and manually include each part that you need in your project. Its not nice and definetely a hazzle, but since Xceed releases only twice a year it might be an OK effort compared to accepting that AvalonDock crashes your application (just because the user was using it as intended).

Maybe someone else in the comunity has a better idea but this is what I can come up with right now.

I wrote an article about lessons learned for designing and implementing WPF control/theme libraries because I noticed that (even in the 'real' opensource comunity) many authors tend to suck all kinds of functionality and dependencies into one huge product. The end of that is that you have huge follow up costs when you actually want to change from one product to another, or there are things that are very hard to do, like not using AvalonDock, but only the toolkit, or vice versa, or or or ...inflexibility and additional costs are definetely part of the equation just because someone wasn't able to release more than one package ...this is the reason why I have so many control projects and even MLib consists of more than one nuget package...

sa-he commented 5 years ago

If you fork the wpftoolkit repo, you have everything, not just AvalonDock and could therefor provide a nuget feature-equal package like "Extended.Wpf.Toolkit.Fixed". In case xceed some day decides to accept pull requests, you could just integrate these changes into your fork.

Then, users could switch between "Extended.Wpf.Toolkit" and "Extended.Wpf.Toolkit.Fixed" as required.

Dirkster99 commented 5 years ago

Yeah, this equation has just one little issue - which is that I am not interested in other parts of the Extended.Wpf.Toolkit and I am already maintaining 6 AvalonDock nuget packages as it is. So, you are asking me to add another 6th package (with way more lines of codes and controls) and also fix that for you because xceed won't do it? Well, I don't think I can do that time wise and since I am not being payed by xceed I am certainly not doing their work for something I don't need.

If someone else wants to contribute the other part of the toolkit I am open to suggestions...

sa-he commented 5 years ago

In case anyone else is intrested in having this fix asap - here is a full copy of the wpftoolkit that includes the fix: https://www.nuget.org/packages/Extended.Wpf.Toolkit.Fixed/ I'm happy to include other bugfixes on receiving pull request. The idea is however, to drop this fork once the next official xceed release is available.

Dirkster99 commented 5 years ago

I recommend including the current binaries for AvalonDock from here: https://ci.appveyor.com/project/Dirkster99/AvalonDock/build/artifacts

I am wondering if there is a free for open source cloud service pipeline we could use to merge results from multiple projects into one nuget, let me know if there is and whether there is something I can do about it...

jogibear9988 commented 5 years ago

@sa-he I mange a fixed Version of WpfToolkit without Avalondock, see https://github.com/dotnetprojects/WpfExtendedToolkit