Forum Replies Created

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • rabjen-iwes
    Participant
    Post count: 8

    I just wanted to give a followup that I got it to work now. I didn’t send you demo code because this problem occurred in company code I am not allowed to give away.

    I still don’t know what exactly was the culprit, but I redesigned some parts of my application the following way:

    – I put my Anchorable-specific stuff in an interface IPanel that has all the necessary things like the title, Content ID, and a property referencing a FrameworkElement that displays the actual panel
    – I created an AnchorableViewModel that has a property which is a reference to my IPanel and a Visibility property
    – this AnchorableViewModel is now in the same assembly as the one where I construct the Dock (my former Panel class I directly used as the view model was defined in another assembly)
    – I wire up the AnchorableViewModel accordingly in XAML

    Plus, since I do all my UI stuff highly asynchronously with a lot of async/await and Tasks, and using Dispatcher.InvokeAsync a lot to update my ObservableCollections, I cleaned that part up, too. maybe there was some race condition.

    rabjen-iwes
    Participant
    Post count: 8

    Followup:

    This is the stack trace:

    
    System.NullReferenceException was unhandled by user code
      HResult=-2147467261
      Message=Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
      Source=Xceed.Wpf.AvalonDock
      StackTrace:
           bei Xceed.Wpf.AvalonDock.Controls.LayoutItem.get_View()
           bei Xceed.Wpf.AvalonDock.DockingManager.RemoveViewFromLogicalChild(LayoutContent layoutContent)
           bei Xceed.Wpf.AvalonDock.DockingManager.DetachAnchorablesSource(LayoutRoot layout, IEnumerable anchorablesSource)
           bei Xceed.Wpf.AvalonDock.DockingManager.OnLayoutChanged(LayoutRoot oldLayout, LayoutRoot newLayout)
           bei Xceed.Wpf.AvalonDock.DockingManager.OnLayoutChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
           bei System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
           bei System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
           bei System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
           bei System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
           bei System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
           bei System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
           bei Xceed.Wpf.AvalonDock.DockingManager.set_Layout(LayoutRoot value)
           bei Xceed.Wpf.AvalonDock.Layout.Serialization.XmlLayoutSerializer.Deserialize(TextReader reader)
           bei My.App.ViewModel.Behavior.AvalonDockLayoutSerializer.LoadLayout(DockingManager dm, String layoutXml) in C:\Somewhere\MyApp\ViewModel\Behavior\AvalonDockLayoutSerializer.cs:Zeile 108.
           bei My.App.ViewModel.MainViewModel.<>c__DisplayClass3_1.<LoadLayout>b__1() in C:\Somewhere\MyApp\ViewModel\MainViewModel.cs:Zeile 46.
           bei System.Windows.Threading.DispatcherOperation.InvokeDelegateCore()
           bei System.Windows.Threading.DispatcherOperation.InvokeImpl()
      InnerException: 
    

    I got it to work in the meantime, with a crude hack using reflection.

    This is what I do:

    
    
            public static void LoadLayout(this DockingManager dm, string layoutXml) {
                // Walk down the layout and gather the LayoutContent elements.
                // AD bails out when it tries to invoke RemoveViewFromLogicalChild
                // on them.
                var l = GatherLayoutContent(dm.Layout).ToArray();
                // Remove the views by force
                foreach(var x in l) {
                    dm.GetType()
                        .GetMethods(BindingFlags.Instance | BindingFlags.NonPublic)
                        .Where(m => m.Name.Equals("RemoveViewFromLogicalChild"))
                        .First()
                        .Invoke(dm, new object[] { x });
                }
                // Now, the deserialization works
                using(var sr = new StringReader(layoutXml)) {
                    var ser = new XmlLayoutSerializer(dm);
                    ser.Deserialize(sr);
                }
            }
    
            private static IEnumerable<LayoutContent> GatherLayoutContent(ILayoutElement le) {
                if(le is LayoutContent) {
                    yield return (LayoutContent)le;
                }
                IEnumerable<ILayoutElement> children = new ILayoutElement[0];
                if(le is LayoutRoot) {
                    children = ((LayoutRoot)le).Children;
                } else if(le is LayoutPanel) {
                    children = ((LayoutPanel)le).Children;
                } else if(le is LayoutDocumentPaneGroup) {
                    children = ((LayoutDocumentPaneGroup)le).Children;
                } else if(le is LayoutAnchorablePane) {
                    children = ((LayoutAnchorablePane)le).Children;
                } else if(le is LayoutDocumentPane) {
                    children = ((LayoutDocumentPane)le).Children;
                }
                foreach(var child in children) {
                    foreach(var x in GatherLayoutContent(child)) {
                        yield return x;
                    }
                }
            }
    

    Needless to say, I want to get rid of this hack. So, did I find a bug or am I missing something?

    rabjen-iwes
    Participant
    Post count: 8

    Followup: After I removed the custom LayoutUpdateStrategy and the default Layout, this works. Thanks for the help 🙂

    rabjen-iwes
    Participant
    Post count: 8

    Thanks, I actually forgot this… I will test this ASAP.

    rabjen-iwes
    Participant
    Post count: 8

    Followup

    I investigated the example and my code a bit more, and in the example, the author sets the data context in code behind. When I do this, it works for me, too.

    Moreover, I did the following experiment: I made the Pages property privately writable, initialized it with null and used a Timer which sets the view models after one second. When I do this, I get the titles, too.

    Is this a bug or do I have to do some additional stuff to make the binding appear without codebehind?

Viewing 5 posts - 1 through 5 (of 5 total)