첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

■ 메트로 UI 사용하기

------------------------------------------------------------------------------------------------------------------------

 


TestProject.zip



MetroStyle.cs

 

 

using System.ComponentModel;

using System.Drawing;

 

namespace TestProject

{

    /// <summary>

    /// 메트로 스타일

    /// </summary>

    public class MetroStyle : INotifyPropertyChanged

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Event

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 속성 변경시 - PropertyChanged

 

        /// <summary>

        /// 속성 변경시

        /// </summary>

        public event PropertyChangedEventHandler PropertyChanged;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// 베이스 폰트

        /// </summary>

        private Font baseFont;

 

        /// <summary>

        /// 볼드체 폰트

        /// </summary>

        private Font boldFont;

 

        /// <summary>

        /// 라이트 폰트

        /// </summary>

        private Font lightFont;

 

        /// <summary>

        /// 배경색

        /// </summary>

        private Color backColor;

 

        /// <summary>

        /// 전경색

        /// </summary>

        private Color foreColor;

 

        /// <summary>

        /// 강조색

        /// </summary>

        private Color accentColor;

 

        /// <summary>

        /// 강조 전경색

        /// </summary>

        private Color accentForeColor;

 

        /// <summary>

        /// 비활성화 색

        /// </summary>

        private Color disabledColor;

 

        /// <summary>

        /// 다크 스타일 여부

        /// </summary>

        private bool isDarkStyle;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 베이스 폰트 - BaseFont

 

        /// <summary>

        /// 베이스 폰트

        /// </summary>

        public Font BaseFont

        {

            get

            {

                return this.baseFont;

            }

            set

            {

                if(value.Equals(this.baseFont) == false)

                {

                    this.baseFont = value;

 

                    FirePropertyChanged("BaseFont");

                }

            }

        }

 

        #endregion

        #region 볼드체 폰트 - BoldFont

 

        /// <summary>

        /// 볼드체 폰트

        /// </summary>

        public Font BoldFont

        {

            get

            {

                return this.boldFont;

            }

            set

            {

                if(value.Equals(this.boldFont) == false)

                {

                    this.boldFont = value;

 

                    FirePropertyChanged("BoldFont");

                }

            }

        }

 

        #endregion

        #region 라이트 폰트 - LightFont

 

        /// <summary>

        /// 라이트 폰트

        /// </summary>

        public Font LightFont

        {

            get

            {

                return this.lightFont;

            }

            set

            {

                if(value.Equals(this.lightFont) == false)

                {

                    this.lightFont = value;

 

                    FirePropertyChanged("LightFont");

                }

            }

        }

 

        #endregion

        #region 배경색 - BackColor

 

        /// <summary>

        /// 배경색

        /// </summary>

        public Color BackColor

        {

            get

            {

                return this.backColor;

            }

            set

            {

                if(value.Equals(this.backColor) == false)

                {

                    this.backColor = value;

 

                    FirePropertyChanged("BackColor");

                }

            }

        }

 

        #endregion

        #region 전경색 - ForeColor

 

        /// <summary>

        /// 전경색

        /// </summary>

        public Color ForeColor

        {

            get

            {

                return this.foreColor;

            }

            set

            {

                if(value.Equals(this.foreColor) == false)

                {

                    this.foreColor = value;

 

                    FirePropertyChanged("ForeColor");

                }

            }

        }

 

        #endregion

        #region 강조색 - AccentColor

 

        /// <summary>

        /// 강조색

        /// </summary>

        public Color AccentColor

        {

            get

            {

                return this.accentColor;

            }

            set

            {

                if(value.Equals(this.accentColor) == false)

                {

                    this.accentColor = value;

 

                    FirePropertyChanged("AccentColor");

                }

            }

        }

 

        #endregion

        #region 강조 전경색 - AccentForeColor

 

        /// <summary>

        /// 강조 전경색

        /// </summary>

        public Color AccentForeColor

        {

            get

            {

                return this.accentForeColor;

            }

            set

            {

                if(value.Equals(this.accentForeColor) == false)

                {

                    this.accentForeColor = value;

 

                    FirePropertyChanged("AccentForeColor");

                }

            }

        }

 

        #endregion

        #region 비활성화 색 - DisabledColor

 

        /// <summary>

        /// 비활성화 색

        /// </summary>

        public Color DisabledColor

        {

            get

            {

                return this.disabledColor;

            }

            set

            {

                if(value.Equals(this.disabledColor) == false)

                {

                    this.disabledColor = value;

 

                    FirePropertyChanged("DisabledColor");

                }

            }

        }

 

        #endregion

        #region 다크 스타일 여부 - IsDarkStyle

 

        /// <summary>

        /// 다크 스타일 여부

        /// </summary>

        public bool IsDarkStyle

        {

            get

            {

                return this.isDarkStyle;

            }

            set

            {

                if(value != this.isDarkStyle)

                {

                    this.isDarkStyle = value;

 

                    if(this.isDarkStyle)

                    {

                        BackColor       = Color.FromArgb(51, 51, 51);

                        ForeColor       = Color.White;

                        AccentColor     = Color.DarkOrange;

                        AccentForeColor = Color.FromArgb(51, 51, 51);

                        DisabledColor   = Color.DimGray;

                    }

                    else

                    {

                        BackColor       = Color.White;

                        ForeColor       = Color.FromArgb(51, 51, 51);

                        AccentColor     = Color.FromArgb(0, 114, 198);

                        AccentForeColor = Color.White;

                        DisabledColor   = Color.DimGray;

                    }

 

                    FirePropertyChanged("IsDarkStyle");

                }

            }

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - MetroStyle()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MetroStyle()

        {

            BaseFont  = new Font("Segoe UI"      , 11.25f                   );

            BoldFont  = new Font("Segoe UI"      , 11.25f, FontStyle.Bold   );

            LightFont = new Font("Segoe UI Light", 11.25f, FontStyle.Regular);

 

            IsDarkStyle = false;

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 속성 변경시 이벤트 발생시키기 - FirePropertyChanged(propertyName)

 

        /// <summary>

        /// 속성 변경시 이벤트 발생시키기

        /// </summary>

        /// <param name="propertyName">property name</param>

        public void FirePropertyChanged(string propertyName)

        {

            if(PropertyChanged != null)

            {

                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

            }

        }

 

        #endregion

    }

}

 

 

MetroUI.cs

 

 

using System.Diagnostics;

 

namespace TestProject

{

    /// <summary>

    /// 메트로 UI

    /// </summary>

    public static class MetroUI

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Private

        

        #region Field

 

        /// <summary>

        /// 메트로 스타일

        /// </summary>

        private static MetroStyle _metroStyle;

 

        /// <summary>

        /// 디자인 모드 여부

        /// </summary>

        private static bool _idDesignMode;

 

        /// <summary>

        /// 초기화 여부

        /// </summary>

        private static bool _isInitialized;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Public

 

        #region 디자인 모드 여부 - IsDesignMode

 

        /// <summary>

        /// 디자인 모드 여부

        /// </summary>

        public static bool IsDesignMode

        {

            get

            {

                if(_isInitialized == false)

                {

                    Initialize();

                }

                

                return _idDesignMode;

            }

        }

 

        #endregion

        #region 스타일 - Style

 

        /// <summary>

        /// 스타일

        /// </summary>

        public static MetroStyle Style

        {

            get

            {

                if(_metroStyle == null)

                {

                    _metroStyle = new MetroStyle();

                }

 

                return _metroStyle;

            }

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region 초기화 하기 - Initialize()

 

        /// <summary>

        /// 초기화 하기

        /// </summary>

        private static void Initialize()

        {

            _idDesignMode = (Process.GetCurrentProcess().ProcessName == "devenv");

 

            _isInitialized = true;

        }

 

        #endregion

    }

}

 

 

MetroToolStripRenderer.cs

 

 

using System.Windows.Forms;

 

namespace TestProject

{

    /// <summary>

    /// 메트로 툴 스트립 렌더러

    /// </summary>

    public class MetroToolStripRenderer : ToolStripProfessionalRenderer

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - MetroToolStripRenderer()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MetroToolStripRenderer() : base(new MetroColorTable())

        {

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

 

        #region 항목 텍스트 렌더링시 처리하기 - OnRenderItemText(e)

 

        /// <summary>

        /// 항목 텍스트 렌더링시 처리하기

        /// </summary>

        /// <param name="e">이벤트 인자</param>

        protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)

        {

            if(e.Item.Selected && e.Item.Pressed == false)

            {

                e.TextColor = MetroUI.Style.AccentForeColor;

            }

            else

            {

                e.TextColor = MetroUI.Style.ForeColor;

            }

 

            base.OnRenderItemText(e);

        }

 

        #endregion

        #region 항목 이미지 렌더링시 처리하기 - OnRenderItemImage(e)

 

        /// <summary>

        /// 항목 이미지 렌더링시 처리하기

        /// </summary>

        /// <param name="e">이벤트 인자</param>

        protected override void OnRenderItemImage(ToolStripItemImageRenderEventArgs e)

        {

            if(e.Item.Selected && e.Item.Pressed == false)

            {

                e.Graphics.DrawImageUnscaled(e.Item.Image.AdjustRGBGamma(1f, 1f, 1f, 0.01f), e.ImageRectangle);

            }

            else

            {

                if(MetroUI.Style.IsDarkStyle)

                {

                    e.Graphics.DrawImageUnscaled(e.Item.Image.AdjustRGBGamma(1f, 1f, 1f, 0.01f), e.ImageRectangle);

                }

                else

                {

                    base.OnRenderItemImage(e);

                }

            }

        }

 

        #endregion

    }

}

 

 

MetroMenuStrip.cs

 

 

using System.Windows.Forms;

 

namespace TestProject

{

    /// <summary>

    /// 메트로 메뉴 스트립

    /// </summary>

    public class MetroMenuStrip : MenuStrip

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - MetroMenuStrip()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MetroMenuStrip() : base()

        {

            Renderer  = new MetroToolStripRenderer();

            Font      = MetroUI.Style.BaseFont;

            ForeColor = MetroUI.Style.ForeColor;

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

 

        #region 항목 추가시 처리하기 - OnItemAdded(e)

 

        /// <summary>

        /// 항목 추가시 처리하기

        /// </summary>

        /// <param name="e">이벤트 인자</param>

        protected override void OnItemAdded(ToolStripItemEventArgs e)

        {

            base.OnItemAdded(e);

 

            e.Item.Font      = MetroUI.Style.BaseFont;

            e.Item.ForeColor = MetroUI.Style.ForeColor;

        }

 

        #endregion

    }

}

 

 

MetroToolbar.cs

 

 

using System.Windows.Forms;

 

namespace TestProject

{

    /// <summary>

    /// 메뉴 툴 스트립

    /// </summary>

    public class MetroToolStrip : ToolStrip

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - MetroToolStrip()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MetroToolStrip() : base()

        {

            Renderer  = new MetroToolStripRenderer();

            Font      = MetroUI.Style.BaseFont;

            ForeColor = MetroUI.Style.ForeColor;

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

 

        #region 항목 추가시 처리하기 - OnItemAdded(e)

 

        /// <summary>

        /// 항목 추가시 처리하기

        /// </summary>

        /// <param name="e">이벤트 인자</param>

        protected override void OnItemAdded(ToolStripItemEventArgs e)

        {

            e.Item.Font      = MetroUI.Style.BaseFont;

            e.Item.ForeColor = MetroUI.Style.ForeColor;

 

            base.OnItemAdded(e);

        }

 

        #endregion

    }

}

 

 

ImageExtension.cs

 

 

using System.Drawing;

using System.Drawing.Imaging;

 

namespace TestProject

{

    /// <summary>

    /// 이미지 확장

    /// </summary>

    public static class ImageExtension

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region RGB 감마 조정하기 - AdjustRGBGamma(sourceImage, red, green, blue, gamma)

 

        /// <summary>

        /// RGB 감마 조정하기

        /// </summary>

        /// <param name="sourceImage">소스 이미지</param>

        /// <param name="red">빨강색</param>

        /// <param name="green">녹색</param>

        /// <param name="blue">파랑색</param>

        /// <param name="gamma">감마</param>

        /// <returns>RGB 감마 조정 이미지</returns>

        /// <remarks>

        /// blue (metro) : 0f, 1f, 3f, 0.55f

        /// light grey   : 1f, 1f, 1f, 0.35f

        /// white        : 1f, 1f, 1f, 0.01f

        /// green        : 0f, 2f, 0f, 0.75f

        /// red          : 2f, 0f, 0f, 0.75f

        /// </remarks>

        public static Image AdjustRGBGamma(this Image sourceImage, float red, float green, float blue, float gamma)

        {

            Bitmap targetBitmap = new Bitmap(sourceImage.Width, sourceImage.Height);

 

            ImageAttributes imgAttributes = new ImageAttributes();

 

            ColorMatrix colorMatrix = new ColorMatrix

            (

                new float[][]

                {

                    new float[] { red, 0f   , 0f  , 0f, 0f },

                    new float[] { 0f , green, 0f  , 0f, 0f },

                    new float[] { 0f , 0f   , blue, 0f, 0f },

                    new float[] { 0f , 0f   , 0f  , 1f, 0f },

                    new float[] { 0f , 0f   , 0f  , 0f, 1f },

                }

            );

 

            imgAttributes.ClearColorMatrix();

 

            imgAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

 

            imgAttributes.SetGamma(gamma, ColorAdjustType.Bitmap);

 

            using(Graphics graphics = Graphics.FromImage(targetBitmap))

            {

                graphics.DrawImage

                (

                    sourceImage,

                    new Rectangle(0, 0, sourceImage.Width, sourceImage.Height),

                    0,

                    0,

                    sourceImage.Width,

                    sourceImage.Height,

                    GraphicsUnit.Pixel,

                    imgAttributes

                );

            }

 

            return (Image)targetBitmap;

        }

 

        #endregion

    }

}

 

 

MainForm.cs

 

 

using System;

using System.ComponentModel;

using System.Drawing;

using System.Windows.Forms;

 

namespace TestProject

{

    /// <summary>

    /// 메인 폼

    /// </summary>

    public partial class MainForm : Form

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - MainForm()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MainForm()

        {

            InitializeComponent();

 

            if(MetroUI.IsDesignMode == false)

            {

                MetroUI.Style.PropertyChanged += Style_PropertyChanged;

 

                MetroUI.Style.IsDarkStyle = true;

            }

 

            this.exitApplicationMenuItem.Click += exitApplicationMenuItem_Click;

            this.switchStyleButton.Click       += switchStyleButton_Click;

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

 

        #region 윈도우 메시지 처리하기 - WndProc(message)

 

        /// <summary>

        /// 윈도우 메시지 처리하기

        /// </summary>

        /// <param name="message">메시지</param>

        protected override void WndProc(ref Message message)

        {

            if(message.Msg == 0x84) // WM_NCHITTEST

            {

                message.Result = (IntPtr)0x02;  // HTCAPTION

            }

            else

            {

                base.WndProc(ref message);

            }

        }

 

        #endregion

        #region 크기 조정시 처리하기 - OnResize(e)

 

        /// <summary>

        /// 크기 조정시 처리하기

        /// </summary>

        /// <param name="e">이벤트 인자</param>

        protected override void OnResize(EventArgs e)

        {

            base.OnResize(e);

 

            Invalidate();

        }

 

        #endregion

        #region 페인트시 처리하기 - OnPaint(e)

 

        /// <summary>

        /// 페인트시 처리하기

        /// </summary>

        /// <param name="e">이벤트인자</param>

        protected override void OnPaint(PaintEventArgs e)

        {

            base.OnPaint(e);

 

            using(Pen pen = new Pen(MetroUI.Style.AccentColor))

            {

                e.Graphics.DrawRectangle(pen, 0, 0, Width - 1, Height - 1);

            }

 

            using(SolidBrush brush = new SolidBrush(MetroUI.Style.AccentColor))

            {

                e.Graphics.DrawString(Text.ToUpper(), MetroUI.Style.LightFont, brush, 10, 8);

            }

        }

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region 스타일 속성 변경시 처리하기 - Style_PropertyChanged(sender, e)

 

        /// <summary>

        /// 스타일 속성 변경시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void Style_PropertyChanged(object sender, PropertyChangedEventArgs e)

        {

            if(e.PropertyName == "IsDarkStyle")

            {

                BackColor = MetroUI.Style.BackColor;

 

                Refresh();

            }

        }

 

        #endregion

        #region Exit Application 메뉴 항목 클릭시 처리하기 - exitApplicationMenuItem_Click(sender, e)

 

        /// <summary>

        /// Exit Application 메뉴 항목 클릭시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void exitApplicationMenuItem_Click(object sender, EventArgs e)

        {

            Close();

        }

 

        #endregion

        #region Switch Style 버튼 클릭시 처리하기 - switchStyleButton_Click(sender, e)

 

        /// <summary>

        /// Switch Style 버튼 클릭시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void switchStyleButton_Click(object sender, EventArgs e)

        {

            MetroUI.Style.IsDarkStyle = !(MetroUI.Style.IsDarkStyle);

        }

 

        #endregion

    }

}

 

------------------------------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker

댓글을 달아 주세요