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