Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You want something like this:</p> <p>First <code>VisualWrapper</code> class:</p> <pre><code>[ContentProperty("Child")] public class VisualWrapper : FrameworkElement { public Visual Child { get { return _child; } set { if (_child != null) { RemoveVisualChild(_child); } _child = value; if (_child != null) { AddVisualChild(_child); } } } protected override Visual GetVisualChild(int index) { if (_child != null &amp;&amp; index == 0) { return _child; } else { throw new ArgumentOutOfRangeException("index"); } } protected override int VisualChildrenCount { get { return _child != null ? 1 : 0; } } private Visual _child; } </code></pre> <p>And then <code>VisualTargetPresentationSource</code>:</p> <pre><code>public class VisualTargetPresentationSource : PresentationSource { public VisualTargetPresentationSource(HostVisual hostVisual) { _visualTarget = new VisualTarget(hostVisual); } public override Visual RootVisual { get { return _visualTarget.RootVisual; } set { Visual oldRoot = _visualTarget.RootVisual; // Set the root visual of the VisualTarget. This visual will // now be used to visually compose the scene. _visualTarget.RootVisual = value; // Tell the PresentationSource that the root visual has // changed. This kicks off a bunch of stuff like the // Loaded event. RootChanged(oldRoot, value); // Kickoff layout... UIElement rootElement = value as UIElement; if (rootElement != null) { rootElement.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); rootElement.Arrange(new Rect(rootElement.DesiredSize)); } } } protected override CompositionTarget GetCompositionTargetCore() { return _visualTarget; } public override bool IsDisposed { get { // We don't support disposing this object. return false; } } private VisualTarget _visualTarget; } </code></pre> <p>This in your XAML:</p> <pre><code>&lt;Window x:Class="TestWpfApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:testWpfApp="clr-namespace:TestWpfApp" Title="MainWindow" Height="350" Width="525" xmlns:vw="--NamespaceHere--"&gt; &lt;Grid&gt; &lt;testWpfApp:GifImage x:Name="gifImage" Stretch="None" GifSource="/loading.gif" AutoStart="True" Width="50" Height="50" Margin="0,0,300,0"/&gt; &lt;ComboBox Width="200" Height="40" Name="Cb"&gt;&lt;/ComboBox&gt; &lt;vw:VisualWrapper Height="160" Width="160" VerticalAlignment="Center" HorizontalAlignment="Center" x:Name="visualWrapper" /&gt; &lt;/Grid&gt; &lt;/Window&gt; </code></pre> <p>Then <code>LoadingPanel</code> class:</p> <pre><code>public class LoadingPanel { private VisualWrapper.VisualWrapper visualWrapper; public LoadingPanel(VisualWrapper.VisualWrapper _visualWrapper) { visualWrapper = _visualWrapper; } public VisualWrapper.VisualWrapper VisualWrapper { get { return visualWrapper; } set { visualWrapper = value; } } #region WaitDailog public HostVisual CreateMediaElementOnWorkerThread() { // Create the HostVisual that will "contain" the VisualTarget // on the worker thread. HostVisual hostVisual = new HostVisual(); // Spin up a worker thread, and pass it the HostVisual that it // should be part of. Thread thread = new Thread(new ParameterizedThreadStart(MediaWorkerThread)); thread.SetApartmentState(ApartmentState.STA); thread.IsBackground = true; thread.Start(new object[] { hostVisual, visualWrapper }); // Wait for the worker thread to spin up and create the VisualTarget. s_event.WaitOne(); return hostVisual; } private FrameworkElement CreateMediaElement(VisualWrapper visualWrapper) { BitmapImage bi = new BitmapImage(new Uri(--YOURIMAGEPATH--));//Image path goes here Image image = new Image(); image.Source = bi; image.Height = 150; image.Width = 150; //image.Margin = new Thickness(-150, -150, -150, -150); ImageBehavior.SetAnimatedSource(image, bi);//See http://wpfanimatedgif.codeplex.com/ BrushConverter conv = new BrushConverter(); //SolidColorBrush brush = conv.ConvertFromString("#6C8BBA") as SolidColorBrush; Border border = new Border(); border.Background = Brushes.Transparent; //border.BorderBrush = brush; //border.BorderThickness = new Thickness(3); //border.Margin = new Thickness(-85, -140, 0, 0); border.Child = image; return border; } private void MediaWorkerThread(object arg) { // Create the VisualTargetPresentationSource and then signal the // calling thread, so that it can continue without waiting for us. HostVisual hostVisual = (HostVisual)((object[])arg)[0]; VisualWrapper visualWrapper = (VisualWrapper)((object[])arg)[1]; VisualTargetPresentationSource visualTargetPS = new VisualTargetPresentationSource(hostVisual); s_event.Set(); // Create a MediaElement and use it as the root visual for the // VisualTarget. visualTargetPS.RootVisual = CreateMediaElement(visualWrapper); // Run a dispatcher for this worker thread. This is the central // processing loop for WPF. System.Windows.Threading.Dispatcher.Run(); } private static AutoResetEvent s_event = new AutoResetEvent(false); public bool ShowWaitDialog() { if (visualWrapper != null) { if (visualWrapper.Child == null) { visualWrapper.Child = CreateMediaElementOnWorkerThread(); } } return true; } public bool DisposeWaitDialog() { if (visualWrapper != null) { visualWrapper.Child = null; } return true; } #endregion } </code></pre> <p>The in code:</p> <pre><code>public MainWindow() { InitializeComponent(); VisualWrapper visualWrapper = (VisualWrapper)this.FindName("visualWrapper"); LoadingPanel loadingPanel = new LoadingPanel(visualWrapper); Dispatcher.Invoke((Action)(() =&gt; { loadingPanel.ShowWaitDialog(); }), DispatcherPriority.Send, null); Task.Factory.StartNew(() =&gt; { List&lt;string&gt; list = new List&lt;string&gt;(); for (int i = 0; i &lt; 14000; i++) { list.Add("Item number" + i); } Dispatcher.BeginInvoke((Action)(() =&gt; { Cb.ItemsSource = list; }), DispatcherPriority.Normal, null); }, TaskCreationOptions.LongRunning); } </code></pre> <p>Edit <code>VirtualizingStackPanel</code>:</p> <pre><code>An easy way to implement this is to create an ItemsPanelTemplate as a Resource and reference it in the ComboBox markup. &lt;Window.Resources&gt; &lt;ItemsPanelTemplate x:Key="VSP"&gt; &lt;VirtualizingStackPanel/&gt; &lt;/ItemsPanelTemplate&gt; &lt;/Window.Resources&gt; &lt;ComboBox Height="23" Margin="27,10,10,0" Name="ComboBox1" VerticalAlignment="Top" ItemsSource="{Binding}" ItemsPanel="{StaticResource VSP}" ScrollViewer.IsDeferredScrollingEnabled="True"&gt; &lt;/ComboBox&gt; Specifically, the ItemsPanel property of the ComboBox is set to that ItemsPanelTemplate Resource. If you prefer, you can include the VirtualizingStackPanel right in the ComboBox creation markup: &lt;ComboBox Height="23" Margin="27,10,10,0" Name="ComboBox1" VerticalAlignment="Top" ItemsSource="{Binding}" ScrollViewer.IsDeferredScrollingEnabled="True"&gt; &lt;ComboBox.ItemsPanel&gt; &lt;ItemsPanelTemplate&gt; &lt;VirtualizingStackPanel /&gt; &lt;/ItemsPanelTemplate&gt; &lt;/ComboBox.ItemsPanel&gt; &lt;/ComboBox&gt; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload