2016-04-20 90 views
0

我想爲我的UserControl創建一個快照,該快照尚未顯示。 這是我的代碼:創建未顯示的UserControl的快照

public Screenshot(MyViewModel viewModel) 
    { 
     if (viewModel == null) 
      return; 

     // Create a TabControl, where View is hosted in 
     var visualTab = new TabControl(); 
     visualTab.Width = FrameworkAdjustments.VisualSize.Width; 
     visualTab.Height = FrameworkAdjustments.VisualSize.Height; 
     visualTab.TabStripPlacement = Dock.Left; 

     // Tabs should only be shown, if there are more than one 'SubView' 
     Visibility tabVisibility = Visibility.Collapsed; 
     if (viewModel.SubViews.Count > 1) 
      tabVisibility = Visibility.Visible; 
     foreach (var subView in viewModel.SubViews) 
     { 
      var tab = new TabItem(); 
      tab.Header = subView.TranslatedId; // multilanguage header 
      tab.Visibility = tabVisibility; 
      if (subView.Id == viewModel.ActiveSubView.Id) 
      { 
       tab.IsSelected = true; 
       // Without the following line my UI works, but my TabControl is empty. 
       tab.Content = ViewManager.GetViewById(subView.Id); 
       // ViewManager.GetViewById(subView.Id); returns a UserControl 
      } 

      tab.Measure(FrameworkAdjustments.VisualSize); 
      tab.Arrange(new Rect(FrameworkAdjustments.VisualSize)); 
      visualTab.Items.Add(tab); 
     } 

     _ContentCtrl = new ContentControl() { Width = FrameworkAdjustments.VisualSize.Width, Height = FrameworkAdjustments.VisualSize.Height }; 
     _ContentCtrl.Content = visualTab; 
     _ContentCtrl.Measure(FrameworkAdjustments.VisualSize); 
     _ContentCtrl.Arrange(new Rect(FrameworkAdjustments.VisualSize)); 

     RenderTargetBitmap bmp = new RenderTargetBitmap((int)FrameworkAdjustments.VisualSize.Width, (int)FrameworkAdjustments.VisualSize.Height, 96, 96, PixelFormats.Pbgra32); 
     bmp.Render(_ContentCtrl); 

     this.ItemBrush = new ImageBrush(bmp); 
    } 

此代碼運行每個「MyViewModel」當我開始我的應用程序。 'MyViewModel'包含一個'SubViews'列表,它們是Tabs的內容,它們包含一個'FunctionKeyBar',這些按鈕可以通過使用'F1'到'F12'來激活。但創建我的屏幕截圖後,我無法再使用F1至F12。還有其他問題,如切換語言。 有沒有其他的方式來創建一個控件的快照,但沒有進入視圖?

感謝您的回覆。

問候尼

回答

0

方法:設置Margin負將它隱藏起來,該控件添加到網格/任何其他容器。

enter image description here

遵循以下步驟:

1)創建一個Task創建並添加ContentControlGrid

2)調用用戶自定義CaptureScreen()函數。

3)Visibility一定不能隱藏/摺疊。 Margin可能爲負值以隱藏控件。

在這個例子中,我在Button.Click中做過這個。

async private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    Task<ContentControl> t = AddContentControl(); 
    ContentControl ctrl = await t; 

    RenderTargetBitmap bmp = CaptureScreen(ctrl, 5000, 5000); 
    Img.Source = bmp; 
} 
/* Add the ContentControl to the Grid, and keep it hidden using neg. Margin */ 
private Task<ContentControl> AddContentControl() 
{ 
    Task<ContentControl> task = Task.Factory.StartNew(() => 
    { 
     ContentControl ctrl = null; 
     Dispatcher.Invoke(() => 
     { 

      ctrl = new ContentControl() { Content = "Not shown", Width = 100, Height = 25, Margin = new Thickness(-8888, 53, 0, 0) }; 
      Grd.Children.Add(ctrl); 
     }); 

     return ctrl; 
    }); 

    return task; 
} 
/* Important , wont work with Visibility.Collapse or Hidden */ 
private static RenderTargetBitmap CaptureScreen(Visual target, double dpiX, double dpiY) 
{ 
    if (target == null) 
    { 
     return null; 
    } 
    Rect bounds = VisualTreeHelper.GetDescendantBounds(target); 
    RenderTargetBitmap rtb = new RenderTargetBitmap((int)(bounds.Width * dpiX/96.0), 
                (int)(bounds.Height * dpiY/96.0), 
                dpiX, 
                dpiY, 
                PixelFormats.Pbgra32); 
    DrawingVisual dv = new DrawingVisual(); 
    using (DrawingContext ctx = dv.RenderOpen()) 
    { 
     VisualBrush vb = new VisualBrush(target); 
     ctx.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size)); 
    } 
    rtb.Render(dv); 
    return rtb; 
} 
+0

你好AnjumSKhan,感謝您的快速回復。我的問題是,我想向用戶顯示預覽,所以在拍攝快照之前,我無法將_ContentControl放入可視化樹中。 – Benny

+0

@Benny PLZ看到更新的答案,就像一個魅力。 – AnjumSKhan

+0

我已經試過了,但這不是我的問題的解決方案。我必須使用.NET 4.0,它在'異步等待'模式上有很多不同之處。另一件事是,我最多有5個實例(取決於配置)'MyViewModel',其中我想在加載我的應用程序後拍攝截圖(或縮略圖)。 我在一個測試項目中嘗試了你的解決方案,它非常好,但在我的情況下,它會導致很多渲染,這會降低我的性能。 – Benny

0

現在我找到了一個解決方案,這要感謝AnjumSKan。 我把他的代碼改了一下。正如我所說的,我需要在應用程序啓動或文化變化時創建快照,並且我擁有多個視圖。在我的功能AddContentControl中,我將內容添加到具有負邊距的我的TabControl。添加結束我打電話​​

('HiddenTab'是我的TabControl不顯示給用戶)。這稱爲CreateSnapshotOnRender函數,我從中調用AnjumSKhan的CaptureScreen-方法。之後,我再次調用功能AddContentControl與我的下一個內容。這看起來如下:

private void CreateScreenshotOnRender() 
    { 
     HiddenTab.Measure(ViewSize); 
     HiddenTab.Arrange(new Rect(ViewSize)); 
     var snapshot = CaptureScreen(HiddenTab, dpiX, dpiY); 
/* Do anything with snapshot */ 
     _Index++;  // counter to know thich view is next 
     CreateAllScreenshots(); 
    } 

再次感謝AnjumSKan,因爲你帶我到這。這就是爲什麼我把你的答案標記爲正確的答案。