Как сделать пользовательский элемент управления, загруженный с помощью LoadComponent, в растровое изображение / изображение в WPF? - PullRequest
0 голосов
/ 13 июля 2010

Я пытаюсь что-то в этом духе.

//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 Ответ

1 голос
/ 13 июля 2010

Что вы хотите сделать, это использовать класс VisualBrush, встроенный в WPF. Это должно обеспечить функциональность, которую, я думаю, вы ищете.

Класс VisualBrush на MSDN

Приветствие.

РЕДАКТИРОВАТЬ: Расширенный ответ на расширенный вопрос

Этот фрагмент кода должен указывать правильное направление для сохранения изображения в файл.

Блог Стефана Вика - Перевод чернил и изображений в растровое изображение с использованием 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;
        }
    }
}

Надеюсь, это немного приблизит вас ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...