SELECT 문으로 조회한 데이터를 객체에 저장을 한 뒤 그 객체의 내용을 수정을 하려 했는데

 

code 5 Database is lock 이라는 에러가 발생했습니다.

 

각각의 쿼리를 실행했을 때는 문제 없이 조회도 되고 수정도 되었습니다.

 

그런데 꼭 같이 실행할 때는 DB에서 lock 이 걸려 데이터 수정이 안됩니다.

 

왜 그런지 물어보아 알아보니 쿼리 실행 후 종료가 안된 상태에서 다시 다른 쿼리를 실행하려 할 때 Lock이 걸릴 수 있다 하여 코드를 살펴보았습니다.

 

그래서 처음 찾은 해결책은 SELECT 쿼리를 실행 후 객체에 저장한 뒤

 

GC.Close();

GC.WaitForPendingFinalizers();

 

두 구문을 추가해주니 정상적으로 동작하는 것을 확인했습니다.

 

다른 방법이 또 있나 찾아보다가

 

SQLiteDataReader 동작 완료 후 reader.close() 로 SQLiteDataReader을 닫아주니 GC 없이도 제대로 동작되는 것을 확인했습니다.

 

결국 쿼리 실행 후 데이터를 읽고 저장한 후 닫지를 않아 발생한 문제로 확인되었습니다.

 

 

 

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

Winform에 있는 TreeView 컨트롤을 생성합니다.

 

	#region Form1()

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

			CreateTreeView();
		}

		#endregion

		#region CreateTreeView()

		/// <summary>
		/// 트리뷰를 생성합니다.
		/// </summary>
		private void CreateTreeView()
		{
			this.exampleTreeView.BeginUpdate();

			this.exampleTreeView.Nodes.Add("가");

			this.exampleTreeView.Nodes[0].Nodes.Add("가-1");

			this.exampleTreeView.Nodes[0].Nodes.Add("가-2");
			this.exampleTreeView.Nodes[0].Nodes[1].Nodes.Add("가-1-1");
			this.exampleTreeView.Nodes[0].Nodes[1].Nodes[0].Nodes.Add("가-1-1-1");
			this.exampleTreeView.EndUpdate();

		}

	#endregion

 

 

 

객체를 GridControl의 DataSource에 바인딩 한 후 컬럼 생성 될때 컬럼의 FieldName과 객체의 속성 값이 일치 해야 GridView에 정상적으로 출력됩니다.

 

FiledName과 일치 하지 않을 경우 출력될 때 빈칸으로 출력이 되는 상황이 발생합니다.

 

아래와 같은 속성들이 있을 때 각 컬럼의 FieldName과 속성들을 매칭한 코드 입니다.

 

this.listGridView.Columns[0].FieldName = "ID";
this.listGridView.Columns[1].FieldName = "Subject";
this.listGridView.Columns[2].FieldName = "UseYN";
this.listGridView.Columns[3].FieldName = "CreateDate";
this.listGridView.Columns[4].FieldName = "UpdateDate";
using System;

namespace InfoListDEV
{
    /// <summary>
    /// InformationModel 클래스 입니다.
    /// </summary>
    public class InformationModel
    {
        #region ID
        /// <summary>
        /// 아이디 입니다.
        /// </summary>
        public string ID { get; set; }

        #endregion
        #region Subject
        /// <summary>
        /// 제목 입니다.
        /// </summary>
        public string Subject { get; set; }

        #endregion
        #region UseYN
        /// <summary>
        /// 사용 여부 입니다.
        /// </summary>
        public string UseYN { get; set; }

        #endregion
        #region CreateDate
        /// <summary>
        /// 생성일 입니다.
        /// </summary>
        public DateTime CreateDate { get; set; }

        #endregion
        #region UpdateDate
        /// <summary>
        /// 수정일 입니다.
        /// </summary>
        public DateTime UpdateDate { get; set; }

        #endregion
        
    }
}

 

 

Column Header와 행의 폰트를 변경 할 수 있습니다.

 

// 컬럼 헤더 폰트 변경하기.
this.listGridView.Appearance.HeaderPanel.Font = new System.Drawing.Font("나눔고딕코딩", 12F, System.Drawing.FontStyle.Regular);

// 행 폰트 변경하기.
this.listGridView.Appearance.Row.Font = new System.Drawing.Font("나눔고딕코딩", 12F, System.Drawing.FontStyle.Regular);

SearchControl에 값을 입력하여 CheckedListBoxControl 항목을 필터링 할 수 있습니다.

 

	public partial class Form1 : Form
	{
		#region Form1()

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

			List<Sample> item = new List<Sample>();

			for (int i = 0; i < 5; i++)
			{
				item.Add(new Sample()
				{
					Name = "Sample" + i.ToString()
				});
			}

			this.checkedListBoxControl1.DataSource    = item;
			this.checkedListBoxControl1.DisplayMember = "Name";
			this.checkedListBoxControl1.CheckMember   = "Check";

			CreateSearchControl();
			
		}

		#endregion

		#region CreateSearchControl()

		/// <summary>
		/// SearchControl을 생성합니다.
		/// </summary>
		private void CreateSearchControl()
		{ 
			this.searchControl1.Client	 = this.checkedListBoxControl1;
            this.searchControl1.Name	 = "searchControl1";

            this.searchControl1.Properties.Buttons.AddRange(new DevExpress.XtraEditors.Controls.EditorButton[] 
			{
				new DevExpress.XtraEditors.Repository.ClearButton(),
				new DevExpress.XtraEditors.Repository.SearchButton()
			});

            this.searchControl1.Properties.Client = this.checkedListBoxControl1;
            this.searchControl1.Size			  = new System.Drawing.Size(255, 20);
		}
		#endregion
	}

	public class Sample
	{ 
		/// <summary>
		/// 이름 입니다.
		/// </summary>
		public string Name { get; set; }

		/// <summary>
		/// 체크 여부 입니다.
		/// </summary>
		public bool Check { get; set; }

	}

CheckedListBoxControl 에서 전체 선택 및 전체 선택 해제 하기 입니다.

 

	public partial class Form1 : Form
	{
		#region Form1()

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

			this.checkedListBoxControl1.Items.Add("Check All");
			this.checkedListBoxControl1.Items.AddRange(new object[] { "가", "나", "다", "라", "마",});

			this.checkedListBoxControl1.ItemCheck += checkedListBoxControl1_ItemCheck;
		}

		#endregion

		#region checkedListBoxControl1_ItemCheck(sender, e)

		/// <summary>
		/// 아이템을 체크할 때 동작합니다.
		/// </summary>
		/// <param name="sender">이벤트 발생자 입니다.</param>
		/// <param name="e">이벤트 인자 입니다.</param>
		private void checkedListBoxControl1_ItemCheck(object sender, DevExpress.XtraEditors.Controls.ItemCheckEventArgs e)
		{
			if (e.Index == 0)
			{
				if (e.State == CheckState.Checked)
				{
					this.checkedListBoxControl1.CheckAll();
					this.checkedListBoxControl1.Items[0].Description = "UnCheckAll";
				}
				else
				{
					this.checkedListBoxControl1.UnCheckAll();
					this.checkedListBoxControl1.Items[0].Description = "CheckAll";
				}
			}
		}
		#endregion
	}

GridLookUpEdit 컨트롤에 새로운 값을 추가할 수 있습니다.

 

기존의 존재하는 값을 사용하거나 새로운 문자열을 입력할 수 있습니다.

 

using DevExpress.XtraEditors;
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace WindowsFormsApp4
{
	public partial class Form1 : Form
	{
		#region Form1()

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

			InitLookUpEdit();
			InitGridLookUpEdit();
		}

		#endregion

		#region InitLookUpEdit()

		/// <summary>
		/// LookUpEdit를 설정 합니다.
		/// </summary>
		private void InitLookUpEdit()
		{
			this.lookUpEdit1.EditValueChanged += lookUpEdit1_EditValueChanged;

			this.lookUpEdit1.Properties.NullText = "(Select or Type Value)";

			string[] colors = new string[]
			{
				"Yellow", "Red", "Green", "Black", "White"
			};

			this.lookUpEdit1.Properties.DataSource				   = colors;

			this.lookUpEdit1.Properties.TextEditStyle			   = DevExpress.XtraEditors.Controls.TextEditStyles.Standard;

			this.lookUpEdit1.Properties.AcceptEditorTextAsNewValue = DevExpress.Utils.DefaultBoolean.Default;
		}

		#endregion

		#region InitGridLookUpEdit()

		/// <summary>
		/// GridLookUpEdit을 설정 합니다.
		/// </summary>
		private void InitGridLookUpEdit()
		{
			this.gridLookUpEdit1.EditValueChanged    += gridLookUpEdit1_EditValueChanged;

			this.gridLookUpEdit1.Properties.NullText = "(Select or Type Value)";

			List<Sample> item = new List<Sample>
			{
				new Sample(){ Name = "가"},
				new Sample(){ Name = "나"},
				new Sample(){ Name = "다"},
				new Sample(){ Name = "라"},
				new Sample(){ Name = "마"},
				new Sample(){ Name = "바"}
			};

			this.gridLookUpEdit1.Properties.DataSource				   = item;
			this.gridLookUpEdit1.Properties.TextEditStyle		       = DevExpress.XtraEditors.Controls.TextEditStyles.Standard;
			this.gridLookUpEdit1.Properties.AcceptEditorTextAsNewValue = DevExpress.Utils.DefaultBoolean.True;
			this.gridLookUpEdit1.Properties.ValueMember				   = "Name";
			this.gridLookUpEdit1.Properties.DisplayMember			   = this.gridLookUpEdit1.Properties.ValueMember;
			this.gridLookUpEdit1.ProcessNewValue					  += gridLookUpEdit1_ProcessNewValue;
		}

		Dictionary<LookUpEditBase, LabelControl> labelDictionaryCore;
		Dictionary<LookUpEditBase, LabelControl> labelDictionary
		{
			get 
			{
				if (labelDictionaryCore == null)
				{
					labelDictionaryCore = new Dictionary<LookUpEditBase, LabelControl>();
					labelDictionaryCore.Add(lookUpEdit1,     labelControl1);
					labelDictionaryCore.Add(gridLookUpEdit1, labelControl2);
				}

				return labelDictionaryCore;
			}	
		}


		#region gridLookUpEdit1_ProcessNewValue(sender, e)

		/// <summary>
		/// GridLookUpEdit에 새로운 값을 추가합니다.
		/// </summary>
		/// <param name="sender">이벤트 발생자입니다.</param>
		/// <param name="e">이벤트 인자입니다.</param>
		private void gridLookUpEdit1_ProcessNewValue(object sender, DevExpress.XtraEditors.Controls.ProcessNewValueEventArgs e)
		{
			GridLookUpEdit gridLookup = sender as GridLookUpEdit;

			if (e.DisplayValue == null)
			{ 
				return;
			} 

            string newValue = e.DisplayValue.ToString();

			if (newValue == String.Empty)
			{ 
				return;
			} 
            if (MessageBox.Show(this, "Add '" + newValue + "' to list?", "Confirm", MessageBoxButtons.YesNo) == DialogResult.Yes) 
			{
                List<Sample> ds = gridLookup.Properties.DataSource as List<Sample>;
                ds.Add(new Sample { Name = newValue });
                e.Handled = true;
            }
		}



		#endregion

		#region lookUpEdit1_EditValueChanged(sender, e)

		/// <summary>
		/// GridLookUpEdit의 값이 변경됩니다.
		/// </summary>
		/// <param name="sender">이벤트 발생자입니다.</param>
		/// <param name="e">이벤트 인자입니다.</param>
		private void gridLookUpEdit1_EditValueChanged(object sender, EventArgs e)
		{
			LookUpEditBase lookupEditor = sender as LookUpEditBase;

			if (lookupEditor == null)
			{ 
				return;
			} 
            LabelControl label = labelDictionary[lookupEditor];

			if (label == null) 
			{
				return;
			}
			if (lookupEditor.EditValue == null)
			{
				label.Text = "Current EditValue: null";
			}
			else
			{ 
				label.Text = "Current EditValue: " + lookupEditor.EditValue.ToString();
			}
                
		}

		#endregion


		#region lookUpEdit1_EditValueChanged(sender, e)

		/// <summary>
		/// LookUpEdit의 값이 변경될 때 동작합니다.
		/// </summary>
		/// <param name="sender">이벤트 발생자입니다.</param>
		/// <param name="e">이벤트 인자입니다.</param>
		private void lookUpEdit1_EditValueChanged(object sender, EventArgs e)
		{
			LookUpEditBase lookupEditor = sender as LookUpEditBase;

			if (lookupEditor == null)
			{ 
				return;
			}
            
			LabelControl label = labelDictionary[lookupEditor];

			if (label == null) 
			{ 
				return;
			}
			if (lookupEditor.EditValue == null)
			{
				label.Text = "Current EditValue: null";
			}
			else
			{ 
				label.Text = "Current EditValue: " + lookupEditor.EditValue.ToString();
			}
                
        }

		#endregion

	}

	#endregion

	/// <summary>
	/// Sample 클래스 입니다.
	/// </summary>
	public class Sample
	{ 
		/// <summary>
		/// 이름 입니다.
		/// </summary>
		public string Name { get; set; }
	}
}

 

 

 

 

 

 

CheckedComboBoxEdit에 열겨형 값을 표시할 수 있습니다.

 

using DevExpress.XtraEditors;
using System;
using System.Windows.Forms;

namespace WindowsFormsApp4
{
	public partial class Form1 : Form
	{

        /// <summary>
        /// Color 열거형 입니다.
        /// </summary>
        enum MyColors
        { 
            None   = 0x00,
            Black  = 0x01,
            White  = 0x02,
            Blue   = 0x04,
            Yellow = 0x08,
            Green  = Blue | Yellow
        }

        #region Form1()

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

            this.checkedComboBoxEdit1.Properties.SetFlags(typeof(MyColors));

            RemoveCombinedFlags(this.checkedComboBoxEdit1);

            this.checkedComboBoxEdit1.SetEditValue(MyColors.Black | MyColors.Green);
        }

        #endregion

        #region RemoveCombinedFlags(checkedComboBoxEdit)

        /// <summary>
        /// 복합 플래그에 해당하는 항목을 제거합니다.
        /// </summary>
        /// <param name="checkedComboBoxEdit">CheckedComboBoxEdit 입니다.</param>
        private void RemoveCombinedFlags(CheckedComboBoxEdit checkedComboBoxEdit)
        {
            for (int i = checkedComboBoxEdit.Properties.Items.Count - 1; i > 0; i--)
            {
                Enum value1 = checkedComboBoxEdit.Properties.Items[i].Value as Enum;

                for (int j = i - 1; j >= 0; j--)
                {
                    Enum value2 = checkedComboBoxEdit.Properties.Items[j].Value as Enum;
                    if (value1.HasFlag(value2))
                    {
                        checkedComboBoxEdit.Properties.Items.RemoveAt(i);
                        break;
                    }
                }
            }
        }
    
		#endregion
	}
}

+ Recent posts