2012-01-31 3 views
2

C#, VisualStudio 2010을 사용하고 Windows Forms 응용 프로그램에 대한 사용자 지정 UserControl을 만들었습니다. 그들은 자신을 드러내고 다른 곳으로 끌고 갈 수있는 것을 제외하고는 많은 행동을하지 않습니다. 그러나 그들은 모양이 원형이고 구석에 겹칠 때 정확하게 표시 할 수 없습니다.겹치는 사용자 컨트롤을 올바르게 표시하려면 어떻게합니까?

다음
public void Circle_Paint(object sender, PaintEventArgs e) 
    { 
    var g = e.Graphics; 

    g.FillEllipse(brushForOuterCircle, 0, 0, Width, Height); 
    g.FillEllipse(brushForInnerCircle, lineWidth, lineWidth, Width - 2*lineWidth, Height - 2*lineWidth); 

    if(!textLocation.HasValue) 
    { 
     SizeF m = g.MeasureString(text, textFont); 
     textLocation = new PointF((float)((Width - m.Width)/2.0), (float)((Height - m.Height)/2.0)); 
    } 
    g.DrawString(text, textFont, brushForText, textLocation.Value); 
    } 

가 잘못 표시, CD는 그 지역을 무시하기 때문에 표시하지 않습니다 AB 원의 남동쪽 부분의 예입니다

다음은 화면에 그림에 대한 내 코드입니다.

enter image description here 어떻게 방지해야 UserControl "기본적으로 투명하게, 내가 그리지 않는 부분은 그렇게 남아 있어야합니다"말할 방법이 있습니까?

+0

가능한 중복 : [.NET에서 투명 사용자 컨트롤 (http://stackoverflow.com/questions/4117356/transparent-user-control-in-net) 확실하게 많은, 많은 다른 질문 : –

+1

나는 그 질문에 대해 알고 있습니다. 그러나 대답은 받아 들였습니다. "작동하지 않는 주목할만한 일은 컨트롤이 겹치는 것입니다. 중복 된 컨트롤의 픽셀이 아닌 부모 픽셀 만 볼 수 있습니다. 코드가 엉망이다. " 그래서 내가 그것을 오해하지 않는다면, 그것은 내 질문에 답하지 않습니다. 그거야? –

답변

3

시도 : 사용자 정의 컨트롤 처음 WS_EX_COMPOSITED 확장 된 스타일에

설치,

으로 배경에 아무것도 페인트하지 않는 후

protected override CreateParams CreateParams 
{ 
    get 
    { 
    CreateParams cp = base.CreateParams; 
    cp.ExStyle |= 0x00000020; // add this 
    return cp; 
    } 
} 

를 오버라이드 (override)

protected override void OnPaintBackground(PaintEventArgs e) 
{ 
    // leave this empty 
} 

및 finall Paint의 y는 모양을 그립니다.

작동해야합니다.

+0

예, 작동합니다. 감사합니다. 참고로 감사드립니다. –

1

시도해보십시오. 여기 제안으로 TransparencyControl 만들기 : Transparent images with C# WinForms

using System; 
using System.Windows.Forms; 
using System.Drawing; 

public class TransparentControl : Control 
{ 
    private readonly Timer refresher; 
    private Image _image; 

    public TransparentControl() 
    { 
     SetStyle(ControlStyles.SupportsTransparentBackColor, true); 
     BackColor = Color.Transparent; 
     refresher = new Timer(); 
     refresher.Tick += TimerOnTick; 
     refresher.Interval = 50; 
     refresher.Enabled = true; 
     refresher.Start(); 
    } 

    protected override CreateParams CreateParams 
    { 
     get 
     { 
      CreateParams cp = base.CreateParams; 
      cp.ExStyle |= 0x20; 
      return cp; 
     } 
    } 

    protected override void OnMove(EventArgs e) 
    { 
     RecreateHandle(); 
    } 


    protected override void OnPaint(PaintEventArgs e) 
    { 
     if (_image != null) 
     { 
      e.Graphics.DrawImage(_image, (Width/2) - (_image.Width/2), (Height/2) - (_image.Height/2)); 
     } 
    } 

    protected override void OnPaintBackground(PaintEventArgs e) 
    { 
     //Do not paint background 
    } 

    //Hack 
    public void Redraw() 
    { 
     RecreateHandle(); 
    } 

    private void TimerOnTick(object source, EventArgs e) 
    { 
     RecreateHandle(); 
     refresher.Stop(); 
    } 

    public Image Image 
    { 
     get 
     { 
      return _image; 
     } 
     set 
     { 
      _image = value; 
      RecreateHandle(); 
     } 
    } 
} 
+0

감사합니다. 두 대답은 본질적으로 같았지만 다른 대답은 더 간단한 대답으로 받아 들였습니다. (정기적인 새로 고침이 필요 없음) –

1

또한 투명해야하는 영역에 대한 마우스 클릭을 무시하도록 영역을 설정해야합니다. 다음 컨트롤을 예로 살펴보십시오. 그것은 원을 칠하는 컨트롤입니다. Region을 타원으로 설정하여 WinForms가 원 밖의 영역을 페인트하지 않게했습니다. 영역을 설정하면 영역 외부의 마우스 클릭을 무시한다는 것도 알고 있습니다.


using System; 
using System.Drawing.Drawing2D; 
using System.Drawing; 
using System.Windows.Forms; 

namespace WindowsApplication1 
{ 
    public class RoundControl : Control 
    { 
     private readonly GraphicsPath _path; 

     public RoundControl() 
     { 
      _path = new GraphicsPath(); 
     } 

     protected override void OnResize(EventArgs e) 
     { 
      _path.Reset(); 
      _path.AddEllipse(ClientRectangle); 
      Invalidate(Region); 
      Region = new Region(_path); 
      base.OnResize(e); 
     } 

     protected override void Dispose(bool disposing) 
     { 
      if (disposing) 
      { 
       _path.Dispose(); 
      } 
      base.Dispose(disposing); 
     } 

     protected override void OnPaint(PaintEventArgs e) 
     { 
      using (Pen borderPen = new Pen(ForeColor, 8)) 
      { 
       e.Graphics.DrawEllipse(borderPen, ClientRectangle); 
      } 
      base.OnPaint(e); 
     } 
    } 
} 

This is what two 'RoundControl' instances look like when rendered in a Form

+0

감사합니다. (대답이 명확 해 지도록 관련이없는 부분 인'ResetBorderPen()','OnFontChanged()','OnForeColorChanged()'를 제거 하시겠습니까?) –

+0

더 간단한 코드로 답변을 업데이트했습니다. –

관련 문제