2010-07-13 3 views
0

나는이 라인을 따라 뭔가를 시도하고있다.WPF에서 LoadComponent를 통해로드 된 usercontrol을 비트 맵/이미지로 렌더링하는 방법은 무엇입니까?

//Somewhere in my app 
System.Uri resourceLocater = new System.Uri("/MyApp;component/Users.xaml", System.UriKind.Relative); 
var obj = Application.LoadComponent(resourceLocater); 

//Invoke the renderxaml element 
var image=RenderXamlElement(obj as UserControl); 

//Then I may save this image to a file.. 





//RenderXamlElement looks like this 

byte[] RenderXamlElement(UserControl control) 
      { 
       Rect rect = new Rect(new Size(control.Width,control.Height)); 
       RenderTargetBitmap rtb = new RenderTargetBitmap((int)rect.Right, 
        (int)rect.Bottom, 96d, 96d, System.Windows.Media.PixelFormats.Default); 
       rtb.Render(control); 
       //endcode as PNG 
       BitmapEncoder pngEncoder = new PngBitmapEncoder(); 
       pngEncoder.Frames.Add(BitmapFrame.Create(rtb)); 

       //save to memory stream 
       System.IO.MemoryStream ms = new System.IO.MemoryStream(); 

       pngEncoder.Save(ms); 
       ms.Close(); 
       return ms.ToArray(); 
      } 

사용자 정의 컨트롤의 스냅 샷이 제대로 렌더링되지 않습니다. 이견있는 사람?

답변

1

WPF에 내장 된 VisualBrush 클래스를 사용하면됩니다. 이것은 당신이 찾고 있다고 생각하는 기능을 제공해야합니다.

VisualBrush class on MSDN

건배.

편집 : 확장 된 질문

확장 된 대답이 코드는 파일에 이미지를 저장하기위한 올바른 방향에 투입해야한다.

Stefan Wick's blog - Rendering ink and image to a bitmap using WPF

// render InkCanvas' visual tree to the RenderTargetBitmap 
RenderTargetBitmap targetBitmap = 
    new RenderTargetBitmap((int)inkCanvas1.ActualWidth, 
          (int)inkCanvas1.ActualHeight, 
          96d, 96d, 
          PixelFormats.Default); 
targetBitmap.Render(inkCanvas1); 

// add the RenderTargetBitmap to a Bitmapencoder 
BmpBitmapEncoder encoder = new BmpBitmapEncoder(); 
encoder.Frames.Add(BitmapFrame.Create(targetBitmap)); 

// save file to disk 
FileStream fs = File.Open(fileName, FileMode.OpenOrCreate); 
encoder.Save(fs); 

편집 : 가능한 솔루션을 시도하고 보여주기 위해 더 많은 코드

XAML : 이제 코드 뒤에

<Page 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    x:Class="UsingVisualBrush.PaintingWithVisuals" > 

    <StackPanel Name="MyStackPanel" 
       Orientation="Horizontal" 
       Margin="10" Background="White" 
       HorizontalAlignment="Left" > 
     <Rectangle Name="myRect" Width="150" Height="150" 
       Stroke="Black" Margin="0,0,5,0" Loaded="UserControl_Loaded" > 
     </Rectangle> 
    </StackPanel> 
</Page> 

...

namespace UsingVisualBrush 
{ 
    public partial class PaintingWithVisuals : Page 
    { 
     public PaintingWithVisuals() 
     { 

     } 

     private void UserControl_Loaded(object sender, RoutedEventArgs args) 
     { 
      Uri resourceLocater = new Uri("/component/Users.xaml", UriKind.Relative); 
      var obj = Application.LoadComponent(resourceLocater); 

      // Using UserControl-derived class 
      var mylocatedControl = obj as UserControl; 
      mylocatedControl.Background = Brushes.Blue; 
      mylocatedControl.Width = 20; 
      mylocatedControl.Height = 20; 

      // Using UserControl-derived class 
      var myControl = new UserControl(); 
      myControl.Background = Brushes.Blue; 
      myControl.Width = 20; 
      myControl.Height = 20; 

      // using UIElement-derived class 
      var myVisualBrush = new VisualBrush(); 
      var panel = new StackPanel { Background = Brushes.Transparent }; 
//   panel.Children.Add(new TextBlock { Background = Brushes.Green, Foreground = Brushes.Black, FontSize = 10, Margin = new Thickness(10), Text = "Hello World from Dave" }); 
//   panel.Children.Add(myControl); 
      panel.Children.Add((UserControl)obj); 
      myVisualBrush.Visual = panel; 
      ((UserControl)obj).Background = Brushes.Blue; 
      myRect.Fill = myVisualBrush; 
     } 
    } 
} 

조금 더 가까이에 있기를 바랍니다.

+0

답장을 보내 주셔서 감사합니다. 어쨌든 위의 코드는 inkCanvas1과 같은 Visual과도 작동 할 것입니다. 문제는 LoadComponent를 사용하여 usercontrol을로드 한 다음 질문에 설명 된대로 이미지를 만드는 것입니다. – amazedsaint

+0

VisualBrush MSDN 기사의 C# 코드를 살펴보면 myStackPanel의 할당을 LoadComponent를 사용하여로드 한 UserControl과 함께 VisualBrush .Visual 속성으로 바꾸어보십시오. // myStackPanel을 myVisualBrush의 콘텐츠로 사용하십시오. myVisualBrush.Visual = myStackPanel; // myStackPanel을 예제에서 "obj"로 바꿉니다. –

+0

감사합니다. 시도했지만 결과가 없습니다 – amazedsaint

관련 문제