Вопрос по wpf, visualbrush, wpf-controls, image, rendering – Визуальная кисть с использованием элемента управления, который не отображается?

1

В данный момент я играю с идеей и ударился о кирпичную стену. Я использую консольное приложение для создания визуального элемента управления (точнее DevExpress chartcontrol) в памяти, затем пытаюсь сохранить этот элемент управления в изображении с помощью VisualBrush, но он не работает, потому что (я предполагаю) элемент управления не отображается на экране.

Я поместил свой код ниже, чтобы вы знали, где я на данный момент. Кто-нибудь знает, как я мог бы сохранить этот элемент управления в изображение (в идеале jpg, но что-нибудь подойдет ...) с помощью консольного приложения? Я действительно не хочу отображать его на экране даже в течение миллисекунды, чтобы сохранить его ...

static void sl_CreateDetail(FrameworkElement chartControl1, CreateAreaEventArgs e)
{
        var brush = new VisualBrush(chartControl1);
        var visual = new DrawingVisual();
        DrawingContext context = visual.RenderOpen();

        context.DrawRectangle(brush, null,
            new Rect(0, 0, chartControl1.ActualWidth, chartControl1.ActualHeight));
        context.Close();

        var bmp = new RenderTargetBitmap((int)chartControl1.ActualWidth,
            (int)chartControl1.ActualHeight, 96, 96, PixelFormats.Pbgra32);

        bmp.Render(visual);
        e.Data = bmp;
}

Ваш Ответ

2   ответа
0

Перед рендерингом элемента управления вы должны вручную сделать его макет, вызвавМера а такжеорганизовать, Для этого необходимо указать желаемый размер элемента управления, например, явно установив его свойства ширины и высоты.

Нет необходимости в VisualBrush и DrawingVisual, вы можете напрямую отобразить элемент управления в RenderTargetBitmap.

chartControl1.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
chartControl1.Arrange(new Rect(0, 0, chartControl1.Width, chartControl1.Height));
chartControl1.UpdateLayout();

var bmp = new RenderTargetBitmap((int)chartControl1.ActualWidth,
    (int)chartControl1.ActualHeight, 96, 96, PixelFormats.Pbgra32);

bmp.Render(chartControl1);

Если элемент управления вычисляет предпочтительный размер во время макета (в мере), вы можете использовать егоDesiredSize свойство для рендеринга.

chartControl1.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
chartControl1.Arrange(new Rect(new Point(), chartControl1.DesiredSize));
chartControl1.UpdateLayout();

Отметим также, что поток рендерингаApartmentState должно бытьSTA, В консольном приложении вы можете просто применитьSTAThread атрибут основного метода.

[STAThread]
static void Main(string[] args)
{
    ...
}
Я сделал Измерение / Аранжировать, и это не сработало. У меня уже был материал по теме STA. Мне пришлось быстро изменить свой подход, чтобы что-то работало для небольшой демонстрации. Я вернусь к своему подходу и опробую ваше полное предложение как можно скорее (в ближайшие несколько дней). Faraday
0

Я попробовал Measure (), Arrange () и т. Д., Затем обнаружил, что они работают, если у Visual есть родитель! В моем случае я удалял Visual из одного контейнера, обновлял его свойства (цвет и т. Д.), А затем пытался использовать его в качестве VisualBrush, и он не обновлялся. Оставив его в исходном контейнере на время Measure () и Arrange () исправили его (хотя все это было сделано за кадром).

Похожие вопросы