2009-12-10 3 views
4

Я пытаюсь создать изображение панели и сохранить ее в папку. Проблема состоит в том, что на панели есть полосы прокрутки, и созданное изображение предназначено только для видимой части панели.C# Windows Form Control для изображения?

Код, который я использую, похож на Panel.DrawToImage. Может ли быть какая-либо помощь здесь, чтобы сохранить всю Панель как изображение, а не только видимую часть?

ответ

2

Здесь нет веселых ответов, DrawToBitmap может рисовать только то, что будет видно пользователю. Обычно хитрости, такие как изменение местоположения и размера панели, обычно быстро заканчиваются из-за ограничения размера управления, налагаемого родителем. Сама форма никогда не может быть больше, чем экран, теперь вы также будете зависеть от разрешения видеоадаптера на целевой машине.

Один уродливый взлом - это запустить DrawToBitmap несколько раз, изменив свойство AutoScrollPosition Panel между каждым вызовом. Вам придется сшить полученные изображения вместе. Обратите особое внимание на последнее, конечно, так как оно не будет таким большим, как другие.

Как только вы начнете рассматривать такой код, вам действительно стоит подумать о PrintDocument или генераторе отчетов. Одним из преимуществ этого является то, что распечатка будет выглядеть очистителем heckofalot. Печатные снимки экрана неизменно уродливы из-за огромной разницы в разрешении видео и принтера.

+0

Спасибо! Кажется, это единственный способ на данный момент! Немного работы, хотя !! Еще раз спасибо!! – Shri

+0

Эй, ребята Просто обновление об этом .... Работа была создана для создания того же элемента управления в памяти и определения пользовательской высоты и ширины, а затем вызова функции DrawToBitmap! Был приятный успех! Надеюсь, это поможет другим! – Shri

+1

+1 для PrintDocument – hometoast

0

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

Вы не рассматриваются как это сделать:

 
// Assume pic is the type of PictureBox and the image property is assigned 
PictureBox pic; 

// And that the picturebox is embedded in the Panel variable p. 
p.Controls.Add(pic); 

// ... 

// So why not do this? 
pic.Image.Save(...); 

Метод класса Image Save имеет 5 перегруженные так выбрать один в вашем удобстве.

Надеюсь, это поможет, С уважением, Tom.

+2

Я думаю, он хочет «скриншот» контролировать контейнер на своей форме. – hometoast

+0

@hometoast: О ... Теперь я понимаю ... ummm ... как насчет Alt + PrtScrn и вставить его в mspaint? Или какой-нибудь другой инструмент Screen grabber? Короче говоря, ответ не такой, как захват экрана, что там, независимо от того, обрезано ли изображение или нет! – t0mm13b

1

Рассмотрим временно увеличивая размер на панели, называя p.Layout(), затем p.DrawToImage()

+0

В любом случае элемент управления больше, чем размер экрана. Таким образом, полосы прокрутки просто невозможно избавиться! – Shri

1

Может быть, вы могли бы клонировать контроль на другой (скрытой) форме в нужный размер (например, что полосы прокрутки не отображаются) и вызовите функцию DrawToImage() таким образом?

4

Я думаю, что сообщение WM_PRINT будет полезно. Вот пример, который работает почти. (Он по-прежнему печатает полосы прокрутки, а фон теряется на участках «из прокрутки».) Возможно, вы можете играть с этим и заставить его работать, или кто-то с большим опытом WinForms может перейти на следующий уровень?

Объявляет следующее в своем классе:

[DllImport("user32.dll")] 
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); 

private const int WM_PRINT = 791; 

/// <summary> 
/// The WM_PRINT drawing options 
/// </summary> 
[Flags] 
private enum DrawingOptions 
{ 
    /// <summary> 
    /// Draws the window only if it is visible. 
    /// </summary> 
    PRF_CHECKVISIBLE = 1, 

    /// <summary> 
    /// Draws the nonclient area of the window. 
    /// </summary> 
    PRF_NONCLIENT = 2, 
    /// <summary> 

    /// Draws the client area of the window. 
    /// </summary> 
    PRF_CLIENT = 4, 

    /// <summary> 
    /// Erases the background before drawing the window. 
    /// </summary> 
    PRF_ERASEBKGND = 8, 

    /// <summary> 
    /// Draws all visible children windows. 
    /// </summary> 
    PRF_CHILDREN = 16, 

    /// <summary> 
    /// Draws all owned windows. 
    /// </summary> 
    PRF_OWNED = 32 
} 

Затем окрасить управление растровым:

using (Bitmap screenshot = new Bitmap(this.panel1.DisplayRectangle.Width, this.panel1.DisplayRectangle.Height)) 
using (Graphics g = Graphics.FromImage(screenshot)) 
{ 
    try 
    { 
     SendMessage(this.panel1.Handle, WM_PRINT, g.GetHdc().ToInt32(), (int)(DrawingOptions.PRF_CHILDREN | DrawingOptions.PRF_CLIENT | DrawingOptions.PRF_NONCLIENT | DrawingOptions.PRF_OWNED)); 
    } 
    finally 
    { 
     g.ReleaseHdc(); 
    } 
    screenshot.Save("temp.bmp"); 
} 

EDIT: Вот альтернативная стратегия краски, которая может получить Вас что вы ищете. Я делаю некоторые предположения, но, возможно, это сработает. Он рисует фиктивный фон на Bitmap первым, а также удаляет скроллбар:

using (Bitmap screenshot = new Bitmap(this.panel1.DisplayRectangle.Width, this.panel1.DisplayRectangle.Height)) 
using (Graphics g = Graphics.FromImage(screenshot)) 
{ 
    g.FillRectangle(SystemBrushes.Control, 0, 0, screenshot.Width, screenshot.Height); 
    try 
    { 
     SendMessage(this.panel1.Handle, WM_PRINT, g.GetHdc().ToInt32(), (int)(DrawingOptions.PRF_CHILDREN | DrawingOptions.PRF_CLIENT | DrawingOptions.PRF_OWNED)); 
    } 
    finally 
    { 
     g.ReleaseHdc(); 
    } 
    screenshot.Save("temp.bmp"); 
} 
0

Я бы создать растровое изображение с правильным размером (и очистить его с правым цветом или окрасить фоновое изображение панелей к нему), а затем петля над всеми дочерними элементами управления и .DrawToImage каждый из них в нужное место.

0

Вам необходимо сделать свою панель AutoZize=True и AutoScroll=False, чем положить ее в другой контейнер и сделать контейнер AutoScroll=true.

Смежные вопросы