폴더 브라우저 출력하기 입니다.

 

using System.Windows.Forms;

namespace Test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            this.buttonEdit1.ButtonClick += buttonEdit1_ButtonClick;
        }

        #region buttonEdit1_ButtonClick() - 버튼 에디트의 버튼 클릭시 동작합니다.

        /// <summary>
        /// 버튼 에디트의 버튼 클릭시 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void buttonEdit1_ButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            FolderBrowserDialog folderBrowser = new FolderBrowserDialog();

            if(folderBrowser.SelectedPath != null)
            {
                folderBrowser.SelectedPath = this.buttonEdit1.Text;
            }

            if(folderBrowser.ShowDialog() == DialogResult.OK)
            { 
                this.buttonEdit1.Text = folderBrowser.SelectedPath;
            }
        }

        #endregion
    }
}

Winform 다른 객체의 속성을 ListBox로 불러올 때 정상적으로 값이 출력 안될 때 해결방법 입니다.

 

아래의 그림과 같이 리스트 박스에 값이 안나오고 객체 이름이 출력되는 경우에

 

리스트 박스의 속성중 DisplayMember를 설정해주면 됩니다.

 

비정상적으로 출력되는 경우

this.recordListBox.DisplayMember = "Time";

위의 코드와 같이 다른 객체의 속성 값을 리스트 박스의 DisplayMember에 추가해주면 됩니다.

 

 

정상적으로 출력되는 경우

 

Winform의 ListBox에 바인딩 할 때

 

this.listBox.DataSource = sourceList; 와 같이 바로 제네릭 리스트와 같은 데이터를

 

바로 데이터 소스에 넣게 되면 제대로 동작하지 않습니다.

 

이럴 경우 먼저 데이터 소스에 null 값을 넣어준 다음

 

데이터를 데이터 소스에 넣어주게 되면 정상적으로 데이터가 들어갑니다.

 

아래 코드는 예제 소스 입니다.

#region SetListBoxControlData(sourceList) - 리스트 박스 컨트롤 데이터를 설정합니다.

/// <summary>
/// 리스트 박스 컨트롤 데이터를 설정합니다.
/// </summary>
/// <param name="sourceList">소스 리스트</param>
private void SetListBoxControlData(List<TimeModel> sourceList)
{
	this.recordListBox.DataSource = null;

	this.sourceList = sourceList;

	this.recordListBox.DataSource = this.sourceList;

	this.recordListBox.DisplayMember = "Time";

	this.recordListBox.Refresh();
}

#endregion

 

BackgroundWorker로 컨트롤에 접근하기 입니다.

 

using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;

namespace ThreadTest
{
    /// <summary>
    /// 메인폼 클래스 입니다.
    /// </summary>
    public partial class MainForm : Form
    {
        #region Fields
        
        /// <summary>
        /// 백그라운드 워커 입니다.
        /// </summary>
        private BackgroundWorker backgroundWorker;
        
        #endregion

        // Construcotr (Public)

        #region MainForm() - 생성자 입니다.

        /// <summary>
        /// 생성자 입니다.
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            #region 이벤트를 설정합니다.

            this.backgroundWorker = new BackgroundWorker();
        
            this.backgroundWorker.WorkerReportsProgress = true;
            this.backgroundWorker.WorkerSupportsCancellation = true;
            
            this.startButton.Click += startButton_Click;
            this.backgroundWorker.DoWork += backgroundWorker_DoWork;
            this.backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
            this.backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;

            #endregion
        }

        #endregion

        // Event Method (Private)

        #region startButton_Click(sender, e) - 시작 버튼 클릭시 동작합니다.

        /// <summary>
        /// 시작 버튼 클릭시 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void startButton_Click(object sender, EventArgs e)
        {
            this.backgroundWorker.RunWorkerAsync();
        
            this.Enabled = false;
        }

        #endregion

        #region backgroundWorker_DoWork(sender, e) - RunWorkerAsync()가 호출될 때 발생합니다.

        /// <summary>
        /// RunWorkerAsync()가 호출될 때 발생합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            for(int i=0; i<10; i++)
            {
                this.backgroundWorker.ReportProgress(i);
                
                Thread.Sleep(1000);
            }
        }

        #endregion
        #region backgroundWorker_ProgressChanged(sender, e) - ReportProgress(Int32)가 호출될 때 발생합니다.

        /// <summary>
        /// ReportProgress(Int32)가 호출될 때 발생합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.numberDisplayTextBox.Text = e.ProgressPercentage.ToString();
        }

        #endregion
        #region backgroundWorker_RunWorkerCompleted(sender, e) - 백그라운드 작업이 완료되거나 취소되거나 예외를 발생시켰을 때 발생합니다.

        /// <summary>
        /// 백그라운드 작업이 완료되거나 취소되거나 예외를 발생시켰을 때 발생합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.Enabled = true;
        }

        #endregion

    }
}

Thread 사용 시 컨트롤에 접근하기 입니다.

 

Thread를 사용하여 컨트롤에 접근했을 때 cross-thread exception 이 발생합니다.

 

exception 발생 안하고 컨트롤에 접근하는 방법입니다.

 

using System;
using System.Threading;
using System.Windows.Forms;

namespace ThreadTest
{
    /// <summary>
    /// 메인폼 클래스 입니다.
    /// </summary>
    public partial class MainForm : Form
    {
        #region Fields
        
        /// <summary>
        /// 스레드 입니다.
        /// </summary>
        private Thread thread;
        
        #endregion

        // Construcotr (Public)

        #region MainForm() - 생성자 입니다.

        /// <summary>
        /// 생성자 입니다.
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            #region 이벤트를 설정합니다.

            this.startButton.Click += startButton_Click;

            #endregion
        }

        #endregion

        // Event Method (Private)

        #region startButton_Click(sender, e) - 시작 버튼 클릭시 동작합니다.

        /// <summary>
        /// 시작 버튼 클릭시 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void startButton_Click(object sender, EventArgs e)
        {
            this.Enabled = false;

            this.thread = new Thread(new ThreadStart(IncreaseNumber));

            this.thread.Start();
        }

        #endregion

        // Method (Private)

        #region IncreaseNumber() - 숫자를 증가시킵니다.

        /// <summary>
        /// 숫자를 증가시킵니다.
        /// </summary>
        private void IncreaseNumber()
        {
            for(int i = 0; i < 10; i++)
            {
                this.Invoke(new Action(delegate()
                {
                    this.numberDisplayTextBox.Text = i.ToString();
                }));

                Thread.Sleep(1000);
            }

            this.Invoke(new Action(delegate()
            {
                this.Enabled = true;
            }));
        }

        #endregion
    }
}

 

키 다운 이벤트를 만들어서 동작시키려 하였는데 아무 반응이 없을 때

 

KeyPreview 설정이 어떻게 되어 있는지 확인해봐야 합니다.

 

KeyPreview의 값이 false 로 되어 있다면 키 이벤트가 동작이 안되기에

 

this.KeyPreview = true;

 

로 변경해주고 사용하면 됩니다.

 

 

새로운 폰트 설치 후 폰트 적용하려 하였으나 트루타입이 아니라 사용 불가하다는 메시지 출력 시 해결 방법 입니다.

 

우선 참조에 사용할 폰트를 추가한 다음에

 

아래와 같이 코드를 작성하면 사용 가능 합니다.

 

/// <summary>
/// 메인폼 클래스 입니다.
/// </summary>
public partial class MainForm : Form
{
	//Constructor (Public)

	#region MainForm() - 생성자 입니다.
	
	/// <summary>
	/// 생성자 입니다.
	/// </summary>
	public MainForm()
	{
		InitializeComponent();

		PrivateFontCollection privateFont = new PrivateFontCollection();

		privateFont.AddFontFile("digital-7.ttf");

		Font font = new Font(privateFont.Families[0], 50f);

		timerLabel.Font = font;
	}

	#endregion
}

텍스트 박스의 값이 없거나 혹은 NULL 일 경우 메시지 박스를 호출하고 리턴해줄수 있습니다.

 

#region CheckTextEdit(textEdit, mandatory, inputValue, labelName)

/// <summary>
/// 텍스트 에디트를 검사합니다.
/// </summary>
/// <param name="textBox">텍스트 박스 입니다.</param>
/// <param name="mandatory">필수 여부 입니다.</param>
/// <param name="inputValue">입력 값 입니다.</param>
/// <param name="labelName">라벨 이름 입니다.</param>
/// <returns>유효성 여부를 리턴합니다.</returns>
private bool CheckTextEdit(TextBox textBox, bool mandatory, string inputValue, string labelName)
{ 
	if(mandatory)
	{ 
		if(string.IsNullOrEmpty(inputValue))
		{ 
			MessageBox.Show($"{labelName} 항목을 입력해주시기 바랍니다.");

			textEdit.Focus();

			return false;
		}
		else
		{
			return true;
		}
	}
	else
	{ 
		return true;
	}
}

#endregion

 

this.treeView.CheckBoxes = true; 를 작성하면

 

TreeView에 출력되는 노드를 체크박스로 변경할 수 있습니다.

 

SelectedNode.Remove()를 사용하여 여러개의 노드를 체크 후 삭제 시도 시 에러 발생합니다.

 

여러개 항목을 체크 후 삭제 할 때는 별도의 코드를 작성해야 합니다.

 

		private List<TreeNode> checkedNodes = new List<TreeNode>();

		#region Form1()

		/// <summary>
		/// 생성자 입니다.
		/// </summary>
		public Form1()
		{
			InitializeComponent();

			this.addButton.Click	   += addButton_Click;
			this.deleteButton.Click	   += deleteButton_Click;
			this.deleteAllButton.Click += deleteAllButton_Click;

			this.treeView.CheckBoxes = true;
		}

		#endregion

		#region addButton_Click(sender, e)

		/// <summary>
		/// 추가 버튼 입니다.
		/// </summary>
		/// <param name="sender">이벤트 발생자 입니다.</param>
		/// <param name="e">이벤트 인자 입니다.</param>

		private void addButton_Click(object sender, System.EventArgs e)
		{
			this.treeView.Nodes.Add("Books");
			this.treeView.Nodes.Add("Papers");
			this.treeView.Nodes.Add("Folders");

			this.treeView.Nodes[0].Nodes.Add("Book_1");
			this.treeView.Nodes[0].Nodes.Add("Book_2");
			this.treeView.Nodes[0].Nodes.Add("Book_3");

			this.treeView.Nodes[1].Nodes.Add("Paper_1");
			this.treeView.Nodes[1].Nodes.Add("Paper_2");
			this.treeView.Nodes[1].Nodes.Add("Paper_3");
		}

		#endregion
		#region deleteButton_Click(sender, e)

		/// <summary>
		/// 삭제 버튼 입니다.
		/// </summary>
		/// <param name="sender">이벤트 발생자 입니다.</param>
		/// <param name="e">이벤트 인자 입니다.</param>
		private void deleteButton_Click(object sender, System.EventArgs e)
		{
			if (treeView.CheckBoxes = true)
			{
				RemoveCheckedNodes(treeView.Nodes);
			}

			else if (treeView.CheckBoxes = false)
			{
				this.treeView.SelectedNode.Remove();
			}
		}

		#endregion
		#region deleteAllButton_Click(sender, e)

		/// <summary>
		/// 전체 삭제 버튼 입니다.
		/// </summary>
		/// <param name="sender">이벤트 발생자 입니다.</param>
		/// <param name="e">이벤트 인자 입니다.</param>
		private void deleteAllButton_Click(object sender, System.EventArgs e)
		{
			this.treeView.Nodes.Clear();
		}

		#endregion

		#region RemoveCheckedNodes

		/// <summary>
		/// 체크된 노드를 삭제 합니다.
		/// </summary>
		/// <param name="nodes">노드들 입니다.</param>
		private void RemoveCheckedNodes(TreeNodeCollection nodes)
		{
			foreach (TreeNode node in nodes)
			{
				if (node.Checked)
				{
					checkedNodes.Add(node);
				}
				else
				{
					RemoveCheckedNodes(node.Nodes
					);
				}
			}

			foreach (TreeNode checkedNode in checkedNodes)
			{
				nodes.Remove(checkedNode);
			}
		}

		#endregion

추가 버튼 / 삭제 버튼 / 전체 삭제 버튼을 클릭하여 TreeView의 노드를 추가, 삭제 그리고 전체 삭제를 할 수 있습니다.

 

		#region Form1()

		/// <summary>
		/// 생성자 입니다.
		/// </summary>
		public Form1()
		{
			InitializeComponent();

			this.addButton.Click += addButton_Click;
			this.deleteButton.Click += deleteButton_Click;
		}

		#endregion

		#region addButton_Click(sender, e)

		/// <summary>
		/// 추가 버튼 입니다.
		/// </summary>
		/// <param name="sender">이벤트 발생자 입니다.</param>
		/// <param name="e">이벤트 인자 입니다.</param>

		private void addButton_Click(object sender, System.EventArgs e)
		{
			this.treeView.Nodes.Add("Books");
			this.treeView.Nodes.Add("Papers");
			this.treeView.Nodes.Add("Folders");

			this.treeView.Nodes[0].Nodes.Add("Book_1");
			this.treeView.Nodes[0].Nodes.Add("Book_2");
			this.treeView.Nodes[0].Nodes.Add("Book_3");

			this.treeView.Nodes[1].Nodes.Add("Paper_1");
			this.treeView.Nodes[1].Nodes.Add("Paper_2");
			this.treeView.Nodes[1].Nodes.Add("Paper_3");
		}

		#endregion
		#region deleteButton_Click(sender, e)

		/// <summary>
		/// 삭제 버튼 입니다.
		/// </summary>
		/// <param name="sender">이벤트 발생자 입니다.</param>
		/// <param name="e">이벤트 인자 입니다.</param>
		private void deleteButton_Click(object sender, System.EventArgs e)
		{
			this.treeView.SelectedNode.Remove();
		}

		#endregion
        #region deleteAllButton_Click(sender, e)

		/// <summary>
		/// 전체 삭제 버튼 입니다.
		/// </summary>
		/// <param name="sender">이벤트 발생자 입니다.</param>
		/// <param name="e">이벤트 인자 입니다.</param>
		private void deleteAllButton_Click(object sender, System.EventArgs e)
		{
			this.treeView.Nodes.Clear();
		}

		#endregion

+ Recent posts