代码之家  ›  专栏  ›  技术社区  ›  amazedsaint

如何在WPF中将通过LoadComponent加载的usercontrol呈现为位图/图像?

  •  0
  • amazedsaint  · 技术社区  · 15 年前

    我正试着沿着这条路走。

    //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 回复  |  直到 15 年前
        1
  •  1
  •   Dave White John Alexiou    15 年前

    您要做的是使用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);
    

    编辑:更多的代码来尝试和演示可能的解决方案

    <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;
            }
        }
    }
    

    推荐文章