WinForm Control с непрозрачностью - PullRequest
7 голосов
/ 24 мая 2011

У меня есть форма, которая имеет некоторые элементы управления (btnCreateReport, pnlDarkLayer). У меня есть панель, которая подходит для формы (Dock = Fill), и она находится сзади всех элементов управления. Когда пользователь нажимает кнопку btnCreateReportЯ вызываю метод pnlDarkLayer BringToFront и после некоторого вычисления вызываю метод кнопки SendToBack (). Я хочу нарисовать темный слой на элементах управления формы и отключить все элементы управления на форме.Является ли это возможным?Спасибо.

Возможно, этот код поможет вам понять мою цель:

private void btnCreateReport_Click(object sender, EventArgs e)
{
    pnlDarkLayer.BackColor = Color.FromArgb(100, Color.Gray);         

    pnlDarkLayer.BringToFront();
    btnCreateReport.Enabled = false;

    Thread ProcessReport = new Thread(new ThreadStart(ProcessingReport));
    ProcessReport.Start();
    while (ProcessReport.IsAlive)
    {
        Application.DoEvents();
    }
    pnlDarkLayer.SendToBack();

    btnCreateReport.Enabled = true;

}

Этот код скрывает все элементы управления, но я не хочу скрывать элементы управления в форме. Я хочу нарисоватьтемный слой на них. И пользователь должен видеть элементы управления.Мне нужно что-то вроде свойства непрозрачности форм для их элементов управления.

У меня есть тест:

pnlDarkLayer.CreateGraphics().CompositingMode=System.Drawing.Drawing2D.CompositingMode.SourceOver;

Обновление : у меня есть это тестодин: (используйте форму вместо панели)

private void btnCreateReport_Click(object sender, EventArgs e)
{          

    btnCreateReport.Enabled = false;

    frmProgress ProgressForm = new frmProgress();
    ProgressForm.TopLevel = false;
    ProgressForm.Parent = this;
    ProgressForm.BringToFront();
    this.Controls.Add(ProgressForm);
    ProgressForm.Show();

    Thread ProcessReport = new Thread(new ThreadStart(ProcessingReport));
    ProcessReport.Start();

    while (ProcessReport.IsAlive)
    {
        Application.DoEvents();
    }
    ProgressForm.Close();
    btnCreateReport.Enabled = true;

}

Но я не вижу ProgressForm в моей форме.

Ответы [ 2 ]

6 голосов
/ 24 мая 2011

Если я правильно понимаю, вы хотите «затемнить» содержимое формы во время выполнения операции.

Как здесь уже говорили, очень сложно поступить правильно. Но есть способ сделать это легко, с одной оговоркой (см. Ниже).

Посмотрите на этот исходный код:

public partial class Form1 : Form
{
    private Bitmap _background;
    private bool _isShrouded;

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        if (true == _isShrouded && null!=_background)
            e.Graphics.DrawImage(_background, 0, 0);
    }

    public void Shroud()
    {
        if (false == _isShrouded)
        {
            CreateScreenshot();

            HideControls();

            _isShrouded = true;

            this.Invalidate();
        }
    }

    public void Unshroud()
    {
        if (true == _isShrouded)
        {
            ShowControls();

            _isShrouded = false;

            this.Invalidate();
        }


    }

    private void HideControls()
    {
        foreach (Control control in this.Controls)
            control.Visible = false;
    }

    private void ShowControls()
    {
        foreach (Control control in this.Controls)
            control.Visible = true;
    }

    private void CreateScreenshot()
    {
        Rectangle area = this.RectangleToScreen(this.ClientRectangle);
        Bitmap screenGrab = new Bitmap(area.Width, area.Height);

        Brush dark = new SolidBrush(Color.FromArgb(128, Color.Black));

        Graphics g = Graphics.FromImage(screenGrab);
        g.CopyFromScreen(area.Location, Point.Empty, area.Size);
        g.FillRectangle(dark, 0, 0, area.Width, area.Height);
        g.Dispose();

        _background = screenGrab;
    }
}

Класс Form1 имеет два основных метода: Shroud () и Unshroud ().

Метод Shroud () делает снимок формы и копирует его в растровое изображение, которое затем затемняется. Затем элементы управления скрываются, а растровое изображение отображается на форме.

Метод UnShroud () восстанавливает элементы управления и указывает форме больше не рисовать растровое изображение.

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

Он также переопределяет OnPaint (), потому что он должен рисовать фоновое изображение, когда оно «окутано».

Примечание: Оболочка работает, сделав скриншот формы. Это означает, что форма ДОЛЖНА БЫТЬ самой верхней формой в точке окутывания. Если форма скрыта другими формами, они будут включены в скриншот. Я надеюсь, что это не будет проблемой для вас.

Примечание: Как уже было сказано, единственный способ добиться прозрачности в Windows - это полное взаимодействие со всеми задействованными элементами управления, и это трудная задача. Все остальное (включая это решение) на самом деле просто обман.

6 голосов
/ 24 мая 2011

С http://support.microsoft.com/kb/943454

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

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

На странице также приведен пример кода (к сожалению, в vb)чтобы показать, как это делается.

...