рдбрдмрд▓ рдмрдлрд╝рд░рд┐рдВрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ
рдпрд╣рд╛рдБ рдФрд░
рдпрд╣рд╛рдБ рдмрд╣реБрдд рдХреБрдЫ рд▓рд┐рдЦрд╛ рдЧрдпрд╛
рд╣реИ ред
рдпрд╣рд╛рдВ рдЖрдк рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐
рдЬрд╛рд╡рд╛ рдбреАрдмреА рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ C # рдореЗрдВ рдбрдмрд▓ рдмрдлрд░рд┐рдВрдЧ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХреА рдЬрд╛рддреА рд╣реИред рдореИрдВрдиреЗ рдпрд╣рд╛рдВ рдЬреЛ рд▓рд┐рдЦрд╛ рд╣реИ, рдЙрд╕рдореЗрдВ рд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ MSDN рдкрд░ рдкрдврд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рд╡рд░рдг рдХреЗ рдмрд┐рдирд╛ред
рдбрдмрд▓ рдмрдлрд░рд┐рдВрдЧ рдХрд╛ рдореИрдиреНрдпреБрдЕрд▓ рдирд┐рдпрдВрддреНрд░рдг (рдЗрд╕рдХреЗ рдмрд╛рдж DB рдХреЗ рд░реВрдк рдореЗрдВ рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ)
рдбрдмрд▓ рдмрдлрд░рд┐рдВрдЧ рдХреЗ рдореИрдиреБрдЕрд▓ рдирд┐рдпрдВрддреНрд░рдг рдХреЗ рд▓рд┐рдП, .NET рдлреНрд░реЗрдорд╡рд░реНрдХ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд 3 рдХрдХреНрд╖рд╛рдПрдВ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ:
- рдмрдлрд╝рд░рдбреИрдЧреНрд░рд╛рдлрд┐рдХреНрд╕ - рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдХреЗ рдЕрд╕реНрдерд╛рдпреА рднрдВрдбрд╛рд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдмрдлрд░ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдФрд░ рдирд┐рдпрдВрддреНрд░рдг рдХреИрдирд╡рд╛рд╕ рдкрд░ рдЗрд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╕рд╛рдзрди рд╣реИред
- BufferedGraphicsContext - рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рдирдИ BufferedGraphics рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ;
- рдмрдлрд╝рд░рдбреИрдЧреНрд░рд╛рдлрд┐рдХреНрд╕рдореИрдиреЗрдЬрд░ - рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдмрдлрд╝рд░рдбреИрдЧреНрд░рд╛рдлрд╝рд┐рдХреНрд╕рдХреЛрдЯреЗрдХреНрд╕реНрдЯ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
BufferedGraphicsManager
BufferedGraphicsManager рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд░реНрддрдорд╛рди рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбреЛрдореЗрди (
AppDomain ) рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝реЗ
BufferedGraphicsContext рдХреНрд▓рд╛рд╕ рдХреА рдПрдХ рд╡рд╕реНрддреБ рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ,
рдХрд░рдВрдЯ рд╕реНрдерд┐рд░ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рдмрдирд╛рдИ рдЧрдИ
рдмрдлрд╝рд░рдбреИрдЧреНрд░рд╛рдлрд┐рдХреНрд╕рдХреЙрдиреНрдЯреЗрдХреНрд╕ рдХреНрд▓рд╛рд╕ рдХреА рд╡рд╕реНрддреБ рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИред
рдмрдлрд╝рд░рдбрд╛рдЧреНрд░рд╛рдлрд┐рдХреНрд╕рдореИрдиреЗрдЬрд░ рдХреНрд▓рд╛рд╕ рдХрд╛ рд╕реЛрд░реНрд╕ рдХреЛрдб рдпрд╣рд╛рдБ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
public sealed class BufferedGraphicsManager { private static BufferedGraphicsContext bufferedGraphicsContext; public static BufferedGraphicsContext Current { get { return BufferedGraphicsManager.bufferedGraphicsContext; } } static BufferedGraphicsManager() { BufferedGraphicsManager.bufferedGraphicsContext = new BufferedGraphicsContext(); AppDomain.CurrentDomain.ProcessExit += new EventHandler(BufferedGraphicsManager.OnShutdown); AppDomain.CurrentDomain.DomainUnload += new EventHandler(BufferedGraphicsManager.OnShutdown); } private static void OnShutdown(object sender, EventArgs e) { BufferedGraphicsManager.Current.Invalidate(); } }
рдЗрд╕ рдХреЛрдб рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐
рдмрдлрд╝рд░рдбреИрдЧреНрд░рд╛рдлрд╝рд┐рдХреНрд╕рдХреЙрдиреНрдЯреЗрдХреНрд╕реНрдЯ рдХреНрд▓рд╛рд╕ рдСрдмреНрдЬреЗрдХреНрдЯ
рдмрдлрд╝рд░рдбрдЧреНрд░рд╛рдлрд┐рдХреНрд╕рдореИрдиреЗрдЬрд░ рдХреЗ рдЕрдВрджрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрдм рд╡рд░реНрддрдорд╛рди рдХрд░рдВрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбреЛрдореЗрди рдЕрдирд▓реЛрдб рд╣реЛрдиреЗ рдкрд░ рдирд╖реНрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
BufferedGraphicsContext
BufferedGraphicsContext рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдЖрдзрд╛рд░рд┐рдд
BufferedGraphics рдХреЗ рдПрдХ рдирдП рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдирд┐рд░реНрдорд╛рдг (рд╕рд╛рде рд╣реА рд╡рд┐рдирд╛рд╢) рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХрдорд╛рддреНрд░
рдЖрд╡рдВрдЯрди рд╡рд┐рдзрд┐ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ:
public BufferedGraphics Allocate(Graphics targetGraphics, Rectangle targetRectangle) { if (targetRectangle.Width * targetRectangle.Height > this.MaximumBuffer.Width * this.MaximumBuffer.Height) return this.AllocBufferInTempManager(targetGraphics, IntPtr.Zero, targetRectangle); else return this.AllocBuffer(targetGraphics, IntPtr.Zero, targetRectangle); }
рд╡рд┐рдзрд┐ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗ рдЬрд╛рддреА рд╣реИ рдПрдХ
рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдФрд░ рдЙрд╕ рдкрд░ рд╡рд╣ рдХреНрд╖реЗрддреНрд░ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдЖрдк рдПрдХ рдмрдлрд░ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
рдпрджрд┐ рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдХреНрд╖реЗрддреНрд░
рдореИрдХреНрд╕рдмрдлрд╝рд░ рд╕рдВрдкрддреНрддрд┐ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреНрд╖реЗрддреНрд░ рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реИ, рддреЛ
рдПрд▓реЛрдХрдмрдлрд╝рд░ рдкрджреНрдзрддрд┐ рдХреЛ
рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рд╕реЗ рдкреНрд░рд╛рдкреНрдд
рдмрдлрд╝рд░рдбреИрдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рд╡рд╛рдкрд╕ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
AllocBuffer рдореЗрдердб рдЕрдкрдиреЗ рдЕрдВрджрд░ рдмрдирд╛рддрд╛ рд╣реИ (
CreateBuffer рдореЗрдердб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ) рдПрдХ рдирдпрд╛ рдСрдл-рд╕реНрдХреНрд░реАрди рдЧреНрд░рд╛рдл, рдЗрд╕реЗ
рдмрдлрд╝рд░рдбреИрдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдореЗрдВ рд▓рдкреЗрдЯрддрд╛ рд╣реИ, рдЗрд╕реЗ
рдмрдлрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдЪрд░ рдореЗрдВ рдмрдЪрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдмрд╛рдж рдореЗрдВ
рдмрдлрд╝рд░рдбрд╛рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдХреЛ рдирд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрдм
рдмрдлрд╝рд░рдбреИрдЧреНрд░рд╛рдлрд╝рд┐рдХреНрд╕рдХреЙрдирдЯреЗрдХреНрд╕реНрдЯ (рдЙрджрд╛рд╣рд░рдг рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ) рдХреА рдПрдХ рдЖрд╡реГрддреНрддрд┐ рдХреЛ рдирд╖реНрдЯ рдХрд░ рджреЗрддрд╛ рд╣реИред
CreateBuffer рд╡рд┐рдзрд┐
рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рдмрд┐рдирд╛ рдСрдл рд╕реНрдХреНрд░реАрди (рдпрд╛рдиреА, рдХреЗрд╡рд▓ рдореЗрдореЛрд░реА рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд, рд╕реНрдХреНрд░реАрди рдкрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдП рдмрд┐рдирд╛) рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдореВрд▓
CreateDIBSection рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП,
рд╡рд╣ рдПрдХ "рдбрд┐рд╡рд╛рдЗрд╕-рд╕реНрд╡рддрдВрддреНрд░ рдмрд┐рдЯрдореИрдк" (DIB) рдмрдирд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╡рд╣ рдПрдХ рдирдпрд╛
рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддрд╛ рд╣реИ, рдФрд░ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░рддрд╛ рд╣реИред
рдпрджрд┐ рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рдХреНрд╖реЗрддреНрд░
рдЕрдзрд┐рдХрддрдордмрдлрд╝рд░ рдХреНрд╖реЗрддреНрд░ рд╕реЗ рдЕрдзрд┐рдХ рд╣реИ, рддреЛ
AllocBufferInTempManager рд╡рд┐рдзрд┐ рдХреЛ
рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ , рдЬрд┐рд╕рдХрд╛ рд╕реНрд░реЛрдд рдХреЛрдб рдиреАрдЪреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
private BufferedGraphics AllocBufferInTempManager(Graphics targetGraphics, IntPtr targetDC, Rectangle targetRectangle) { // "" var bufferedGraphicsContext= new BufferedGraphicsContext(); // (graphics), ( context) // var bufferedGraphics = bufferedGraphicsContext.AllocBuffer(targetGraphics, targetDC, targetRectangle); // , , bufferedGraphics // // bufferedGraphicsContext: bufferedGraphics.DisposeContext = true; return bufferedGraphics; }
рдпрд╣ рдХреЛрдб рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐
AllocBufferInTempManager рд╡рд┐рдзрд┐ рдХреЗ рдЕрдВрджрд░, рдПрдХ рдирдпрд╛
рдмрдлрд╝рд░рдбреИрдЧреНрд░рд╛рдлрд╝рд┐рдХреНрд╕рдХреЙрдиреНрдЯреЗрдХреНрд╕ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬреЛ
рдСрд▓реЛрдХрдмрдлрд╝рд░ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рд╕реЗ рдкреНрд░рд╛рдкреНрдд
рдмрдлрд╝рд░рдбреИрдЧреНрд░рд╛рдлрд╝рд┐рдХреНрд╕ рдХреЛ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рд▓реМрдЯрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдмрдирд╛рдИ рдЧрдИ рдЕрд╕реНрдерд╛рдпреА рдСрдмреНрдЬреЗрдХреНрдЯ
BufferedGraphicsContext рддреБрд░рдВрдд рдирд╖реНрдЯ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рддрдм рд╣реА рдЬрдм рдмрдирд╛рдИ рдЧрдИ
BufferedGraphics рдирд╖реНрдЯ рд╣реЛ рдЬрд╛рддреА рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП,
рдмрдлрд╝рд░рдбреИрдЧреНрд░рд╛рдлрд╝рд┐рдХреНрд╕ рдЕрдкрдиреЗ рдирд┐рд░реНрдорд╛рддрд╛ рдХреЛ рдПрдХ рдмреИрдХрд▓рд┐рдВрдХ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╡рд┐рдирд╛рд╢ рдкрд░, рдпрджрд┐
рдбрд┐рд╕реНрдкреЛрдЬрд╝рдирдЯреЗрдХреНрд╕реНрдЯ рд╕рдВрдкрддреНрддрд┐
рд╕рд╣реА рд╣реИ , рддреЛ рд╡рд╣ рдЗрд╕реЗ рдЕрдкрдиреЗ рд╕рд╛рде рд▓реЗ рдЬрд╛рддреА рд╣реИред
BufferedGraphics
рдмрдлрд░реНрдбрдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдХреНрд▓рд╛рд╕ рдмрд╣реБрдд рдЫреЛрдЯреА рд╣реИред рдЗрд╕рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдореЗрдВ 100 рд╕реЗ рдЕрдзрд┐рдХ рд▓рд╛рдЗрдиреЗрдВ рд╣реЛрддреА рд╣реИрдВред рдпрд╣
рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдПрдХ рд╕рд░рд▓ рдЖрд╡рд░рдг рд╣реИ, рдФрд░ рдЗрд╕реЗ рдХрд┐рд╕реА рдЕрдиреНрдп
рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдкрд░ рдХреЙрдкреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд░реЗрдВрдбрд░ рд╡рд┐рдзрд┐ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ:
public void Render(Graphics target)
рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдирд╛ рдмрд┐рдЯ рдмрд┐рдЯреЗрд▓ рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдСрдЯреЛ рдбреАрдмреА
рд░реЗрдВрдбрд░рд┐рдВрдЧ рдХрдВрдЯреНрд░реЛрд▓ рдХреЗ рд▓рд┐рдП DB рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рд╕рд░рд▓ рддрд░реАрдХрд╛ рд╡рд╛рдВрдЫрд┐рдд рдирд┐рдпрдВрддреНрд░рдг рдХреЗ рд▓рд┐рдП рд╕реНрд╡рдЪрд╛рд▓рд┐рдд DB рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдирд╛ рд╣реИ:
control.DoubleBuffered = true;
рдпрд╛
control.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдХрд┐ рдЬрдм рд╣рдо рдЗрд╕рдХреЗ рд▓рд┐рдП рд╕реНрд╡рдЪрд╛рд▓рд┐рдд DB рдЪрд╛рд▓реВ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдирд┐рдпрдВрддреНрд░рдг рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИред
DoubleBuffered рд╕рдВрдкрддреНрддрд┐,
SetStyle рд╡рд┐рдзрд┐ рдХреА рддрд░рд╣,
рдирд┐рдпрдВрддреНрд░рдг рд╡рд░реНрдЧ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИред рдЗрд╕ рд╡рд░реНрдЧ рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред
DoubleBuffered рд╕рдВрдкрддреНрддрд┐ рдХреЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
protected virtual bool DoubleBuffered { get { return this.GetStyle(ControlStyles.OptimizedDoubleBuffer); } set { if (value != this.DoubleBuffered) { if (value) this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, value); else this.SetStyle(ControlStyles.OptimizedDoubleBuffer, value); } } }
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЗрд╕ рдХреЛрдб рд╕реНрдирд┐рдкреЗрдЯ рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, DBs рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрд░реЛрдХреНрдд 2 рддрд░реАрдХреЗ рдПрдХ рджреВрд╕рд░реЗ рд╕реЗ рдЕрд▓рдЧ рдирд╣реАрдВ рд╣реИрдВ, рд╕рд┐рд╡рд╛рдп рдЗрд╕рдХреЗ рдХрд┐
ControlStyles.AllPaintingInWmPaint рдзреНрд╡рдЬ рднреА
DoubleBuffered рд╕реЗрдЯрд░ рдореЗрдВ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ рдпрд╣ рдзреНрд╡рдЬ рдирд┐рдпрдВрддреНрд░рдг рдирд┐рд░реНрдорд╛рддрд╛
1 рдореЗрдВ рднреА рд╕реЗрдЯ рд╣реИ, рддреЛ рдпрджрд┐ рдЖрдкрдиреЗ рдЗрд╕реЗ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд░реАрд╕реЗрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдЗрди рджреЛрдиреЛрдВ рддрд░реАрдХреЛрдВ рдХрд╛ рдПрдХ рд╣реА рдкреНрд░рднрд╛рд╡ рд╣реИред
рдирд┐рдпрдВрддреНрд░рдг рд╡рд░реНрдЧ рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рд╕реЗ, рдЖрдк рдпрд╣ рднреА рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐
ControlStyles.AllPaintingInWmPaint рдзреНрд╡рдЬ рдХреЛ рдХреЗрд╡рд▓ рдирд┐рдЬреА
WmEraseBkgnd рд╡рд┐рдзрд┐ рдХреЗ рдЕрдВрджрд░ рдЪреЗрдХ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рдФрд░ рдХреЗрд╡рд▓
DoubleBuffered рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд┐рд░реНрдорд╛рддрд╛ рдФрд░ рд╕реЗрдЯрд░ рдореЗрдВ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ), рдЬреЛ
WM_ERASEBKGND 2 рд╕рд┐рд╕реНрдЯрдо рд╕рдВрджреЗрд╢ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╝рд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдпрд╣рд╛рдБ рдЗрд╕рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ:
private void WmEraseBkgnd(ref Message m) { if (this.GetStyle(ControlStyles.UserPaint) && !this.GetStyle(ControlStyles.AllPaintingInWmPaint)) { ... using (PaintEventArgs e = new PaintEventArgs(wparam, ClientRect)) this.PaintWithErrorHandling(e, (short) 1); } ... }
рдЗрд╕рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдЕрдЧрд░
AllPaintingInWmPaint рдзреНрд╡рдЬ рд╕реЗрдЯ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЬрдм рд╡рд┐рдВрдбреЛ
WM_ERASEBKGND рд╕рдВрджреЗрд╢
рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ , рддреЛ
PaintWithErrorHandling рд╡рд┐рдзрд┐ рдХреЛ
рдкрд░рдд рдкреИрд░рд╛рдореАрдЯрд░ 1
3 рдХреЗ рд╕рд╛рде
рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ , рдЬреЛ рдмрджрд▓реЗ рдореЗрдВ рдирд┐рдпрдВрддреНрд░рдг
4 рдХреА рдкреГрд╖реНрдарднреВрдорд┐ рдХреЛ рдлрд┐рд░ рд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рддрд╛ рд╣реИред
рдпрд╣
ControlStyles.UserPaint рдзреНрд╡рдЬ рдкрд░ рднреА рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИред рдпрд╣ рдзреНрд╡рдЬ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдХрд┐ рдирд┐рдпрдВрддреНрд░рдг рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдлреНрд░реЗрдорд╡рд░реНрдХ рдЯреВрд▓реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рди рдХрд┐ рд╕рд┐рд╕реНрдЯрдо рдЯреВрд▓реНрд╕ рдХреЛред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдк рдЕрдкрдиреЗ рдлреЙрд░реНрдо рдХреЗ рд▓рд┐рдП рдкреГрд╖реНрдарднреВрдорд┐ рдХреА рдЫрд╡рд┐ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░
UserPaint рдзреНрд╡рдЬ рдХреЛ рд╕рд╛рдлрд╝ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЪрд┐рддреНрд░ рдирд╣реАрдВ рдЦреАрдВрдЪрд╛ рдЬрд╛рдПрдЧрд╛ред
рдореБрдЦреНрдп DB рдХреНрд░рд┐рдпрд╛
WmPaint рдкрджреНрдзрддрд┐ рдХреЗ рдЕрдВрджрд░ рддреИрдирд╛рдд рдХреА
рдЬрд╛рддреА рд╣реИрдВ ред рдпрд╣ рд╡рд┐рдзрд┐
WM_PAINT рд╕рд┐рд╕реНрдЯрдо рд╕рдВрджреЗрд╢ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╝рд┐рдореНрдореЗрджрд╛рд░ рд╣реИ, рдЬреЛ рддрдм рдЖрддрд╛ рд╣реИ рдЬрдм рдирд┐рдпрдВрддреНрд░рдг рдХреЗ рдХрд┐рд╕реА рднреА рд╣рд┐рд╕реНрд╕реЗ рдХреЛ рдлрд┐рд░ рд╕реЗ рддреИрдпрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
WmPaint рд╡рд┐рдзрд┐ рдирд┐рдЬреА рд╣реИ рдФрд░ рдЗрд╕реЗ рдХреЗрд╡рд▓
WndProc рд╡рд┐рдзрд┐ рд╕реЗ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдмрд╢рд░реНрддреЗ рдХрд┐
ControlStyles.UserPaint рдзреНрд╡рдЬ рд╕реЗрдЯ рд╣реЛ:
protected virtual void WndProc(ref Message m) { switch (m.Msg) { ... case WM_PAINT: if (this.GetStyle(ControlStyles.UserPaint)) this.WmPaint(ref m); break; ... } }
рдпрджрд┐ рд╣рдо рдЧреИрд░-рдбреАрдмреА рд╡рд┐рд╡рд░рдгреЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ, рддреЛ
WmPaint рд╡рд┐рдзрд┐ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЗрд╕ рддрд░рд╣
рджрд┐рдЦрддрд╛ рд╣реИ:
private void WmPaint(ref Message m) { if (this.DoubleBuffered || this.GetStyle(ControlStyles.AllPaintingInWmPaint) && this.DoubleBufferingEnabled) { IntPtr num; // Graphics Rectangle rectangle; // // num rectangle... if (rectangle.Width > 0 && rectangle.Height > 0) { Rectangle clientRectangle = this.ClientRectangle; using (BufferedGraphics bufferedGraphics = BufferedGraphicsManager.Current.Allocate(num, clientRectangle)) { Graphics graphics = bufferedGraphics.Graphics; graphics.SetClip(rectangle); System.Drawing.Drawing2D.GraphicsState gstate = graphics.Save(); using (PaintEventArgs e = new PaintEventArgs(graphics, rectangle)) { this.PaintWithErrorHandling(e, (short) 1, false); graphics.Restore(gstate); this.PaintWithErrorHandling(e, (short) 2, false); bufferedGraphics.Render(); } } } ... } else { // ... } }
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рд╕реНрдирд┐рдкреЗрдЯ рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдбреАрдмреА рдХреЗ рд╕рд╛рде рдЦреАрдВрдЪреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдХреЗ рд▓рд┐рдП,
DoubleBuffered рдХреЛ
рд╕рд╣реА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдпрд╛
ControlStyles.AllPaintingInWPPaint рдлреНрд▓реИрдЧ рдХреЛ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП (
рдбрдмрд▓рдмрд░реНрдлрд░рд┐рдВрдЧ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╣рдореЗрд╢рд╛
рд╕рдЪ 5 рдпрд╣рд╛рдБ рд╣реИ )ред
рдЕрдЧрд▓рд╛, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдмрдлрд╝рд░рдбрдЧреНрд░реИрдлрд╝рд┐рдХреНрд╕рдХреЛрдЯреЗрдХреНрд╕реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдПрдХ рдЧреНрд░рд╛рдлрд┐рдХ рдмрдлрд░ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рд▓рд┐рдП, рдПрдХ рдкреНрд░рддрд┐рдкрд╛рджрди рдЖрдпрдд рдЙрд╕ рдХреНрд╖реЗрддреНрд░ рдХреЗ рдмрд░рд╛рдмрд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдкреБрдирд░реНрд╡рд┐рдХрд╛рд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдФрд░ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдмрдЪ рдЬрд╛рддреА рд╣реИред
рдЙрд╕рдХреЗ рдмрд╛рдж, OnBackgroundPaint рдФрд░ OnPaint рддрд░реАрдХреЛрдВ рдХреЛ PaintWithErrorHandling
3 рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдЪрд┐рддреНрд░ рдирд┐рдпрдВрддреНрд░рдг рдЪрд╛рд░реНрдЯ рдкрд░ рдХреЙрдкреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдмрдлрд╝рд░рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрд╕реА DB рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдореИрдиреБрдЕрд▓ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
1.
рдХрдВрдЯреНрд░реЛрд▓ рдХреНрд▓рд╛рд╕ рдХреЗ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЗ рд╕реЛрд░реНрд╕ рдХреЛрдб рдХрд╛ рдПрдХ рдЯреБрдХрдбрд╝рд╛ рдЬрд┐рд╕рдореЗрдВ
ControlStyles рдЭрдВрдбреЗ рд╕реЗрдЯ рд╣реЛрддреЗ рд╣реИрдВ:
internal Control(bool autoInstallSyncContext) { ... this.SetStyle(ControlStyles.UserPaint | ControlStyles.StandardClick | ControlStyles.Selectable | ControlStyles.StandardDoubleClick | ControlStyles.AllPaintingInWmPaint | ControlStyles.UseTextForAccessibility, true); ... }
2.
WM_ERASEBKGND рд╕рдВрджреЗрд╢ рдирд┐рдпрдВрддреНрд░рдг рдХреЗ рдЖрдХрд╛рд░
рдмрджрд▓рдиреЗ рдкрд░ рдЖрддрд╛ рд╣реИред рд╕реНрд░реЛрдд рдХреЛрдб рдХрд╛ рдПрдХ рдЯреБрдХрдбрд╝рд╛ рдЬрд┐рд╕рдореЗрдВ
WM_ERASEBKGND рд╕рдВрджреЗрд╢
рд╕рдВрд╕рд╛рдзрд┐рдд рд╣реЛрддрд╛
рд╣реИ :
protected virtual void WndProc(ref Message m) { switch (m.Msg) { ... case WM_ERASEBKGND: this.WmEraseBkgnd(ref m); break; ... } }
3. рдкреЗрдВрдЯрд╡рд┐рдердПрдпрд░рд╣реИрдВрдбрд▓рд┐рдВрдЧ рд╡рд┐рдзрд┐ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:
private void PaintWithErrorHandling(PaintEventArgs e, short layer) { ... switch (layer) { case (short) 1: if (!this.GetStyle(ControlStyles.Opaque)) this.OnPaintBackground(e); break; case (short) 2: this.OnPaint(e); break; } ... }
4.
ControlStyles.Opaque рдзреНрд╡рдЬ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдирд┐рдпрдВрддреНрд░рдг рдкреГрд╖реНрдарднреВрдорд┐ рдХреЛ рдлрд┐рд░ рд╕реЗ рдирд╣реАрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред
5. рдирд┐рдЬреА рд╕рдВрдкрддреНрддрд┐
DoubleBufferingEnabled рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ:
bool DoubleBufferingEnabled { private get { return this.GetStyle(ControlStyles.UserPaint | ControlStyles.DoubleBuffer); } }
рдЪреВрдВрдХрд┐ WmPaint рд╡рд┐рдзрд┐ рдХреЛ рдХреЗрд╡рд▓ рддрднреА рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм
ControlStyles.UserPaint рдзреНрд╡рдЬ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ
DoubleBufferingEnabled рд╣рдореЗрд╢рд╛
рдпрд╣рд╛рдВ рд╕рддреНрдп рд╣реЛрдЧрд╛ред рдФрд░ рдЪреВрдВрдХрд┐ рдпрд╣ рдмрдВрдж рд╣реИ рдФрд░
WmPaint рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдХрд╣реАрдВ рднреА рдЪреЗрдХ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИред