External/Aga.Controls/Tree/NodeControls/NodeCheckBox.cs
author sl
Thu, 01 Jan 2015 23:35:49 +0100
changeset 405 5715aefd2bcc
permissions -rw-r--r--
SharpDisplay: Migrating to new robust client scheme.
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Text;
     4 using System.Drawing;
     5 using Aga.Controls.Properties;
     6 using System.Reflection;
     7 using System.Windows.Forms;
     8 using System.Windows.Forms.VisualStyles;
     9 using System.ComponentModel;
    10 
    11 namespace Aga.Controls.Tree.NodeControls
    12 {
    13 	public class NodeCheckBox : InteractiveControl
    14 	{
    15 		public const int ImageSize = 13;
    16 
    17 		private Bitmap _check;
    18 		private Bitmap _uncheck;
    19 		private Bitmap _unknown;
    20 
    21 		#region Properties
    22 
    23 		private bool _threeState;
    24 		[DefaultValue(false)]
    25 		public bool ThreeState
    26 		{
    27 			get { return _threeState; }
    28 			set { _threeState = value; }
    29 		}
    30 
    31 		#endregion
    32 
    33 		public NodeCheckBox()
    34 			: this(string.Empty)
    35 		{
    36 		}
    37 
    38 		public NodeCheckBox(string propertyName)
    39 		{
    40 			_check = Resources.check;
    41 			_uncheck = Resources.uncheck;
    42 			_unknown = Resources.unknown;
    43 			DataPropertyName = propertyName;
    44 			LeftMargin = 0;
    45 		}
    46 
    47 		public override Size MeasureSize(TreeNodeAdv node, DrawContext context)
    48 		{
    49 			return new Size(ImageSize, ImageSize);
    50 		}
    51 
    52 		public override void Draw(TreeNodeAdv node, DrawContext context)
    53 		{
    54 			Rectangle bounds = GetBounds(node, context);
    55 			CheckState state = GetCheckState(node);
    56 			if (Application.RenderWithVisualStyles)
    57 			{
    58 				VisualStyleRenderer renderer;
    59 				if (state == CheckState.Indeterminate)
    60 					renderer = new VisualStyleRenderer(VisualStyleElement.Button.CheckBox.MixedNormal);
    61 				else if (state == CheckState.Checked)
    62 					renderer = new VisualStyleRenderer(VisualStyleElement.Button.CheckBox.CheckedNormal);
    63 				else
    64 					renderer = new VisualStyleRenderer(VisualStyleElement.Button.CheckBox.UncheckedNormal);
    65 				renderer.DrawBackground(context.Graphics, new Rectangle(bounds.X, bounds.Y, ImageSize, ImageSize));
    66 			}
    67 			else
    68 			{
    69 				Image img;
    70 				if (state == CheckState.Indeterminate)
    71 					img = _unknown;
    72 				else if (state == CheckState.Checked)
    73 					img = _check;
    74 				else
    75 					img = _uncheck;
    76 				context.Graphics.DrawImage(img, bounds.Location);
    77 			}
    78 		}
    79 
    80 		protected virtual CheckState GetCheckState(TreeNodeAdv node)
    81 		{
    82 			object obj = GetValue(node);
    83 			if (obj is CheckState)
    84 				return (CheckState)obj;
    85 			else if (obj is bool)
    86 				return (bool)obj ? CheckState.Checked : CheckState.Unchecked;
    87 			else
    88 				return CheckState.Unchecked;
    89 		}
    90 
    91 		protected virtual void SetCheckState(TreeNodeAdv node, CheckState value)
    92 		{
    93 			if (VirtualMode)
    94 			{
    95 				SetValue(node, value);
    96 				OnCheckStateChanged(node);
    97 			}
    98 			else
    99 			{
   100 				Type type = GetPropertyType(node);
   101 				if (type == typeof(CheckState))
   102 				{
   103 					SetValue(node, value);
   104 					OnCheckStateChanged(node);
   105 				}
   106 				else if (type == typeof(bool))
   107 				{
   108 					SetValue(node, value != CheckState.Unchecked);
   109 					OnCheckStateChanged(node);
   110 				}
   111 			}
   112 		}
   113 
   114 		public override void MouseDown(TreeNodeAdvMouseEventArgs args)
   115 		{
   116 			if (args.Button == MouseButtons.Left && IsEditEnabled(args.Node))
   117 			{
   118 				DrawContext context = new DrawContext();
   119 				context.Bounds = args.ControlBounds;
   120 				Rectangle rect = GetBounds(args.Node, context);
   121 				if (rect.Contains(args.ViewLocation))
   122 				{
   123 					CheckState state = GetCheckState(args.Node);
   124 					state = GetNewState(state);
   125 					SetCheckState(args.Node, state);
   126 					Parent.UpdateView();
   127 					args.Handled = true;
   128 				}
   129 			}
   130 		}
   131 
   132 		public override void MouseDoubleClick(TreeNodeAdvMouseEventArgs args)
   133 		{
   134 			args.Handled = true;
   135 		}
   136 
   137 		private CheckState GetNewState(CheckState state)
   138 		{
   139 			if (state == CheckState.Indeterminate)
   140 				return CheckState.Unchecked;
   141 			else if(state == CheckState.Unchecked)
   142 				return CheckState.Checked;
   143 			else 
   144 				return ThreeState ? CheckState.Indeterminate : CheckState.Unchecked;
   145 		}
   146 
   147 		public override void KeyDown(KeyEventArgs args)
   148 		{
   149 			if (args.KeyCode == Keys.Space && EditEnabled)
   150 			{
   151 				Parent.BeginUpdate();
   152 				try
   153 				{
   154 					if (Parent.CurrentNode != null)
   155 					{
   156 						CheckState value = GetNewState(GetCheckState(Parent.CurrentNode));
   157 						foreach (TreeNodeAdv node in Parent.Selection)
   158 							if (IsEditEnabled(node))
   159 								SetCheckState(node, value);
   160 					}
   161 				}
   162 				finally
   163 				{
   164 					Parent.EndUpdate();
   165 				}
   166 				args.Handled = true;
   167 			}
   168 		}
   169 
   170 		public event EventHandler<TreePathEventArgs> CheckStateChanged;
   171 		protected void OnCheckStateChanged(TreePathEventArgs args)
   172 		{
   173 			if (CheckStateChanged != null)
   174 				CheckStateChanged(this, args);
   175 		}
   176 
   177 		protected void OnCheckStateChanged(TreeNodeAdv node)
   178 		{
   179 			TreePath path = this.Parent.GetPath(node);
   180 			OnCheckStateChanged(new TreePathEventArgs(path));
   181 		}
   182 
   183 	}
   184 }