This project is read-only.

DirectX/XNA flickering

Apr 6, 2010 at 7:34 PM

Hi,

I'm using AvalonDock for my 3D World Editor project, which uses XNA. The xna viewport is in a DocumentPane, but whenever I'm hovering over any button (so the window have to be redrawn) the xna window flickers. When I'm hosting xna in a "normal window" (which doesn't use Avalon Dock) it all works fine! Here is some code:

<ad:DockingManager x:Name="_dockManager">
    <ad:ResizingPanel Orientation="Horizontal" >
        <!--Property Grid-->
        <ad:DockablePane HorizontalAlignment="Stretch">
            <ad:DockableContent Title="Properties" Name="dockProp" Visibility="Collapsed" ad:ResizingPanel.ResizeWidth="*">
                <pg:PropertyGrid Instance="{Binding ElementName=dockProp}" IsEnabled="True"/>
            </ad:DockableContent>
        </ad:DockablePane>

        <!--Viewport-->
        <ad:DocumentPane>
            <ad:DockableContent>
               <WindowsFormsHost Name="viewport">
                    <wf:Panel/>
               </WindowsFormsHost> 
            </ad:DockableContent>
        </ad:DocumentPane>

    </ad:ResizingPanel>
</ad:DockingManager>


I hope you can help me. Thanks in advance.

best regards,
Kevin

May 4, 2010 at 3:05 PM

I'm having a similar problem using an open source 3D graphics engine. My toolbar buttons and tooltips refresh OK, but the content of the floating window flickers when the window is moved or resized.

Is there a way to disable the refreshing of a wpf control in a content window? The 3D engine requires a windows handle of the content area for rendering.

 

 

 

May 4, 2010 at 4:10 PM
To alleviate this effect next version (1.3.3000 for .net 4) will handle pane resizing using a preview of the resizer instead of resize contents themselves.
I'm actively working on this version that will be out soon.
Ado

From: AndyQuay
Sent: Tuesday, May 04, 2010 4:05 PM
Subject: Re: DirectX/XNA flickering [AvalonDock:208473]

From: AndyQuay

I'm having a similar problem using an open source 3D graphics engine. My toolbar buttons and tooltips refresh OK, but the content of the floating window flickers when the window is moved or resized.

Is there a way to disable the refreshing of a wpf control in a content window? The 3D engine requires a windows handle of the content area for rendering.

May 8, 2010 at 6:55 PM

Hi,
I did some tests on Direct3D with SlimDx and everything worked fine, because I was responsable to start the rendering each frame.

Maybe you'll have the chance to interrupt the rendering in XNA when the client area is resizing.

 

May 14, 2010 at 10:14 AM

Try to change ManagedContent.cs to the following:

public abstract class ManagedContent : ContentControl, INotifyPropertyChanged
    {
        static ManagedContent()
        {
            //This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
            //This style is defined in themes\generic.xaml
            //DefaultStyleKeyProperty.OverrideMetadata(typeof(ManagedContent), new FrameworkPropertyMetadata(typeof(ManagedContent)));
            FocusableProperty.OverrideMetadata(typeof(ManagedContent), new FrameworkPropertyMetadata(true));
        }

        public ManagedContent()
        {
            this.Loaded += new RoutedEventHandler(ManagedContent_Loaded);
            this.Unloaded += new RoutedEventHandler(ManagedContent_Unloaded);
		}

		WindowsFormsHost GetWinFormsHost(ContentControl control)
		{
			if (control == null)
				return null;

			WindowsFormsHost contentHost = null;
			UIElementCollection collection = null;
			if (control.Content != null)
			{
				PropertyInfo childrenInfo = control.Content.GetType().GetProperty("Children");
				if (childrenInfo != null)
				{
					collection = control.Content.GetType().GetProperty("Children").GetValue(control.Content, null) as UIElementCollection;
				}
			}

			if (collection != null)
			{
				foreach (var item in collection)
				{
					if (item is WindowsFormsHost)
					{
						return item as WindowsFormsHost;
					}
					else
					{
						contentHost = GetWinFormsHost(item as ContentControl);
						if (contentHost is WindowsFormsHost)
						{
							return contentHost;
						}
					}
				}
			}
			else if (control.Content is ContentControl)
			{
				contentHost = GetWinFormsHost(control.Content as ContentControl);
			}
			else if (control.Content is WindowsFormsHost)
			{
				contentHost = control.Content as WindowsFormsHost;
			}

			return contentHost;
		}

		void ManagedContent_SizeChanged(object sender, SizeChangedEventArgs e)
		{
			WindowsFormsHost contentHost = GetWinFormsHost(this);

			if (contentHost != null)
			{
				object childCtrl = contentHost.GetType().GetProperty("Child").GetValue(contentHost, null);

				if (childCtrl != null)
				{
					this.Dispatcher.Invoke(new Action<object>((o) => o.CallMethod("Refresh", null)), DispatcherPriority.Render, childCtrl);
				}
			}
		}

        void ManagedContent_Loaded(object sender, RoutedEventArgs e)
        {
			WindowsFormsHost contentHost = GetWinFormsHost(this);

			if (contentHost != null)
			{
				contentHost.SizeChanged += new SizeChangedEventHandler(ManagedContent_SizeChanged);
			}
        }

        void ManagedContent_Unloaded(object sender, RoutedEventArgs e)
        {
			WindowsFormsHost contentHost = GetWinFormsHost(this);

			if (contentHost != null)
			{
				contentHost.SizeChanged -= new SizeChangedEventHandler(ManagedContent_SizeChanged);
			}
        }


        public string Title
        {
            get { return (string)GetValue(TitleProperty); }
            set { SetValue(TitleProperty, value); }
        }
...

That worked for me. It would be nice if this would enter the version 1.3.

Thanks.