첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
다운로드

▶ ImageItem.cs

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

namespace TestProject
{
    /// <summary>
    /// 이미지 항목
    /// </summary>
    public class ImageItem
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 이미지
        /// </summary>
        public Image Image;

        /// <summary>
        /// 텍스트
        /// </summary>
        public string Text;

        /// <summary>
        /// 폰트
        /// </summary>
        public Font Font;

        #endregion

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

        #region Field

        /// <summary>
        /// 마진 너비
        /// </summary>
        private const int MARGIN_WIDTH = 4;

        /// <summary>
        /// 마진 높이
        /// </summary>
        private const int MARGIN_HEIGHT = 4;

        /// <summary>
        /// 너비
        /// </summary>
        private int width;
        
        /// <summary>
        /// 높이
        /// </summary>
        private int height;

        /// <summary>
        /// 크기 계산 여부
        /// </summary>
        private bool sizeCalculated = false;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - ImageItem(image, text, font)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="image">이미지</param>
        /// <param name="text">텍스트</param>
        /// <param name="font">폰트</param>
        public ImageItem(Image image, string text, Font font)
        {
            Image = image;
            Text  = text;
            Font  = font;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 항목 측정하기 - MeasureItem(e)

        /// <summary>
        /// 항목 측정하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        public void MeasureItem(MeasureItemEventArgs e)
        {
            if(!this.sizeCalculated)
            {
                this.sizeCalculated = true;

                SizeF textSize = e.Graphics.MeasureString(Text, Font);

                this.height = 2 * MARGIN_HEIGHT + (int)Math.Max(Image.Height, textSize.Height);

                this.width = (int)(4 * MARGIN_WIDTH + Image.Width + textSize.Width);
            }

            e.ItemWidth  = this.width;
            e.ItemHeight = this.height;
        }

        #endregion
        #region 항목 그리기 - DrawItem(e)

        /// <summary>
        /// 항목 그리기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        public void DrawItem(DrawItemEventArgs e)
        {
            e.DrawBackground();

            float height = e.Bounds.Height - 2 * MARGIN_HEIGHT;
            float scale  = height / Image.Height;
            float width  = Image.Width * scale;

            RectangleF rectangle = new RectangleF
            (
                e.Bounds.X + MARGIN_WIDTH,
                e.Bounds.Y + MARGIN_HEIGHT,
                width,
                height
            );

            e.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;

            e.Graphics.DrawImage(Image, rectangle);

            string visibleText = Text;

            if(e.Bounds.Height < Image.Height)
            {
                visibleText = Text.Substring(0, Text.IndexOf('\n'));
            }

            width = e.Bounds.Width - rectangle.Right - 3 * MARGIN_WIDTH;

            rectangle = new RectangleF
            (
                rectangle.Right + 2 * MARGIN_WIDTH,
                rectangle.Y,
                width,
                height
            );

            using(StringFormat stringFormat = new StringFormat())
            {
                stringFormat.Alignment     = StringAlignment.Near;
                stringFormat.LineAlignment = StringAlignment.Center;

                e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;

                e.Graphics.DrawString(visibleText, Font, Brushes.Black, rectangle, stringFormat);
            }

            e.Graphics.DrawRectangle(Pens.Blue, Rectangle.Round(rectangle));

            e.DrawFocusRectangle();
        }

        #endregion
    }
}

 

728x90

 

▶ ComboBoxHelper.cs

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

namespace TestProject
{
    /// <summary>
    /// 콤보 박스 헬퍼
    /// </summary>
    public static class ComboBoxHelper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Instance
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 색상 항목 마진 너비
        /// </summary>
        private const int COLOR_ITEM_MARGIN_WIDTH  = 4;

        /// <summary>
        /// 색상 항목 마진 높이
        /// </summary>
        private const int COLOR_ITEM_MARGIN_HEIGHT = 4;

        /// <summary>
        /// 이미지 항목 마진 너비
        /// </summary>
        private const int IMAGE_ITEM_MARGIN_WIDTH  = 2;

        /// <summary>
        /// 이미지 항목 마진 높이
        /// </summary>
        private const int IMAGE_ITEM_MARGIN_HEIGHT = 2;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public
        ////////////////////////////////////////////////////////////////////// Function

        #region 색상 데이터 설정하기 - SetColorData(comboBox, colorArray)

        /// <summary>
        /// 색상 데이터 설정하기
        /// </summary>
        /// <param name="comboBox">콤보 박스</param>
        /// <param name="colorArray">색상 배열</param>
        public static void SetColorData(this ComboBox comboBox, Color[] colorArray)
        {
            comboBox.DrawMode = DrawMode.OwnerDrawFixed;

            comboBox.Items.Clear();

            foreach (Color color in colorArray)
            {
                comboBox.Items.Add(color);
            }

            comboBox.DrawItem += colorComboBox_DrawItem;
        }

        #endregion
        #region 이미지 데이터 설정하기 - SetImageData(comboBox, imageArray)

        /// <summary>
        /// 이미지 데이터 설정하기
        /// </summary>
        /// <param name="comboBox">콤보 박스</param>
        /// <param name="imageArray">이미지 배열</param>
        public static void SetImageData(this ComboBox comboBox, Image[] imageArray)
        {
            comboBox.DrawMode = DrawMode.OwnerDrawVariable;

            comboBox.Items.Clear();

            foreach(Image image in imageArray)
            {
                comboBox.Items.Add(image);
            }

            comboBox.MeasureItem += imageComboBox_MeasureItem;
            comboBox.DrawItem    += imageComboBox_DrawItem;
        }

        #endregion
        #region 이미지 항목 데이터 설정하기 - SetImageItemData(comboBox, imageItemArray)

        /// <summary>
        /// 이미지 항목 데이터 설정하기
        /// </summary>
        /// <param name="comboBox">콤보 박스</param>
        /// <param name="imageItemArray">이미지 항목 배열</param>
        public static void SetImageItemData(this ComboBox comboBox, ImageItem[] imageItemArray)
        {
            comboBox.DrawMode = DrawMode.OwnerDrawVariable;

            comboBox.Items.Clear();

            comboBox.Items.AddRange(imageItemArray);

            comboBox.MeasureItem += imageItemComboBox_MeasureItem;
            comboBox.DrawItem    += imageItemComboBox_DrawItem;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Private
        ////////////////////////////////////////////////////////////////////// Event

        #region 색상 콤보 박스 항목 그리기 - colorComboBox_DrawItem(sender, e)

        /// <summary>
        /// 색상 콤보 박스 항목 그리기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private static void colorComboBox_DrawItem(object sender, DrawItemEventArgs e)
        {
            if(e.Index < 0)
            {
                return;
            }

            e.DrawBackground();

            int height = e.Bounds.Height - 2 * COLOR_ITEM_MARGIN_HEIGHT;

            Rectangle rectangle = new Rectangle
            (
                e.Bounds.X + COLOR_ITEM_MARGIN_WIDTH,
                e.Bounds.Y + COLOR_ITEM_MARGIN_HEIGHT,
                height,
                height
            );

            ComboBox comboBox = sender as ComboBox;

            Color color = (Color)comboBox.Items[e.Index];

            using(SolidBrush brush = new SolidBrush(color))
            {
                e.Graphics.FillRectangle(brush, rectangle);
            }

            e.Graphics.DrawRectangle(Pens.Black, rectangle);

            using(Font font = new Font(comboBox.Font.FontFamily, comboBox.Font.Size * 0.75f, FontStyle.Bold))
            {
                using(StringFormat stringFormat = new StringFormat())
                {
                    stringFormat.Alignment     = StringAlignment.Near;
                    stringFormat.LineAlignment = StringAlignment.Center;

                    int x = height + 2 * COLOR_ITEM_MARGIN_WIDTH;
                    int y = e.Bounds.Y + e.Bounds.Height / 2;

                    e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;

                    e.Graphics.DrawString(color.Name, font, Brushes.Black, x, y, stringFormat);
                }
            }

            e.DrawFocusRectangle();
        }

        #endregion
        #region 이미지 콤보 박스 항목 측정하기 - imageComboBox_MeasureItem(sender, e)

        /// <summary>
        /// 이미지 콤보 박스 항목 측정하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private static void imageComboBox_MeasureItem(object sender, MeasureItemEventArgs e)
        {
            if(e.Index < 0)
            {
                return;
            }

            ComboBox comboBox = sender as ComboBox;

            Image image = (Image)comboBox.Items[e.Index];

            e.ItemHeight = image.Height + 2 * IMAGE_ITEM_MARGIN_HEIGHT;
            e.ItemWidth  = image.Width  + 2 * IMAGE_ITEM_MARGIN_WIDTH;
        }

        #endregion
        #region 이미지 콤보 박스 항목 그리기 - imageComboBox_DrawItem(sender, e)

        /// <summary>
        /// 이미지 콤보 박스 항목 그리기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private static void imageComboBox_DrawItem(object sender, DrawItemEventArgs e)
        {
            if(e.Index < 0)
            {
                return;
            }

            e.DrawBackground();

            ComboBox comboBox = sender as ComboBox;

            Image image = (Image)comboBox.Items[e.Index];

            float height = e.Bounds.Height - 2 * IMAGE_ITEM_MARGIN_HEIGHT;
            float scale  = height / image.Height;
            float width  = image.Width * scale;

            RectangleF rectangle = new RectangleF
            (
                e.Bounds.X + IMAGE_ITEM_MARGIN_WIDTH,
                e.Bounds.Y + IMAGE_ITEM_MARGIN_HEIGHT,
                width,
                height
            );

            e.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;

            e.Graphics.DrawImage(image, rectangle);

            e.DrawFocusRectangle();
        }

        #endregion
        #region 이미지 항목 콤보 박스 항목 측정하기 - imageItemComboBox_MeasureItem(sender, e)

        /// <summary>
        /// 이미지 항목 콤보 박스 항목 측정하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private static void imageItemComboBox_MeasureItem(object sender, MeasureItemEventArgs e)
        {
            if(e.Index < 0)
            {
                return;
            }

            ComboBox comboBox = sender as ComboBox;

            ImageItem item = (ImageItem)comboBox.Items[e.Index];

            item.MeasureItem(e);
        }

        #endregion
        #region 이미지 항목 콤보 박스 항목 그리기 - imageItemComboBox_DrawItem(sender, e)

        /// <summary>
        /// 이미지 항목 콤보 박스 항목 그리기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private static void imageItemComboBox_DrawItem(object sender, DrawItemEventArgs e)
        {
            if(e.Index < 0)
            {
                return;
            }

            ComboBox comboBox = sender as ComboBox;

            ImageItem item = (ImageItem)comboBox.Items[e.Index];

            item.DrawItem(e);
        }

        #endregion
    }
}

 

300x250

 

▶ MainForm.cs

using System;
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();

            #region 이벤트를 설정한다.

            Load += Form_Load;

            #endregion
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

        #region 폼 로드시 처리하기 - Form_Load(sender, e)

        /// <summary>
        /// 폼 로드시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void Form_Load(object sender, EventArgs e)
        {
            Font font = new Font("Times New Roman", 14);

            ImageItem[] imageItemArray =
            {
                new ImageItem
                (
                    Properties.Resources.Mercury,
                    "Name     : Mercury"   + '\n' +
                    "Distance : 0.31-0.47" + '\n' +
                    "Distance : 0.31-0.47" + '\n' +
                    "Mass     : 0.06"      + '\n' +
                    "Diameter : 0.382"     + '\n' +
                    "Year     : 0.24"      + '\n' +
                    "Day      : 58.64",
                    font
                ),
                new ImageItem
                (
                    Properties.Resources.Venus,
                    "Name     : Venus" + '\n' +
                    "Distance : 0.72"  + '\n' +
                    "Mass     : 0.82"  + '\n' +
                    "Diameter : 0.949" + '\n' +
                    "Year     : 0.62"  + '\n' +
                    "Day      : -243.02",
                    font
                ),
                new ImageItem
                (
                    Properties.Resources.Earth,
                    "Name     : Earth" + '\n' +
                    "Distance : 1" + '\n' +
                    "Mass     : 1" + '\n' +
                    "Diameter : 1" + '\n' +
                    "Year     : 1" + '\n' +
                    "Day      : 1",
                    font
                ),
                new ImageItem
                (
                    Properties.Resources.Mars,
                    "Name     : Mars"  + '\n' +
                    "Distance : 1.52"  + '\n' +
                    "Mass     : 0.11"  + '\n' +
                    "Diameter : 0.532" + '\n' +
                    "Year     : 1.88"  + '\n' +
                    "Day      : 1.03",
                    font
                ),
                new ImageItem
                (
                    Properties.Resources.Jupiter,
                    "Name     : Jupiter" + '\n' +
                    "Distance : 5.2"     + '\n' +
                    "Mass     : 317.8"   + '\n' +
                    "Diameter : 11.209"  + '\n' +
                    "Year     : 11.86"   + '\n' +
                    "Day      : 0.41",
                    font
                ),
                new ImageItem
                (
                    Properties.Resources.Saturn,
                    "Name     : Saturn" + '\n' +
                    "Distance : 9.54"   + '\n' +
                    "Mass     : 95.2"   + '\n' +
                    "Diameter : 9.449"  + '\n' +
                    "Year     : 29.46"  + '\n' +
                    "Day      : 0.43",
                    font
                ),
                new ImageItem
                (
                    Properties.Resources.Uranus,
                    "Name     : Uranus" + '\n' +
                    "Distance : 19.22"  + '\n' +
                    "Mass     : 14.6"   + '\n' +
                    "Diameter : 4.007"  + '\n' +
                    "Year     : 84.01"  + '\n' +
                    "Day      : 0.72",
                    font
                ),
                new ImageItem
                (
                    Properties.Resources.Neptune,
                    "Name     : Neptune" + '\n' +
                    "Distance : 30.06"   + '\n' +
                    "Mass     : 17.2"    + '\n' +
                    "Diameter : 3.883"   + '\n' +
                    "Year     : 164.8"   + '\n' +
                    "Day      : 0.67",
                    font
                ),
            };

            this.imageItemComboBox.SetImageItemData(imageItemArray);

            this.imageItemComboBox.SelectedIndex = 0;
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요