423 lines
13 KiB
C#
423 lines
13 KiB
C#
#if FRAMEWORK20
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.ComponentModel;
|
|
using System.Windows.Forms;
|
|
|
|
namespace DevComponents.Editors
|
|
{
|
|
/// <summary>
|
|
/// Represents the group of the input items with automatic and manual item focus change.
|
|
/// </summary>
|
|
public class VisualInputGroup : VisualGroup
|
|
{
|
|
#region Private Variables
|
|
#endregion
|
|
|
|
#region Events
|
|
#endregion
|
|
|
|
#region Constructor
|
|
#endregion
|
|
|
|
#region Internal Implementation
|
|
/// <summary>
|
|
/// Resets the input position so the new input overwrites current value.
|
|
/// </summary>
|
|
public void ResetInputPosition()
|
|
{
|
|
foreach (VisualItem item in this.Items)
|
|
{
|
|
VisualInputBase input = item as VisualInputBase;
|
|
if (input != null)
|
|
input.ResetInputPosition();
|
|
}
|
|
}
|
|
|
|
protected override bool OnCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData)
|
|
{
|
|
if (keyData == Keys.Tab && (Control.ModifierKeys & Keys.Shift) != Keys.Shift && this.TabNavigationEnabled ||
|
|
keyData == Keys.Enter && this.EnterNavigationEnabled ||
|
|
keyData == Keys.Right && this.ArrowNavigationEnabled)
|
|
{
|
|
ValidateInput(this.FocusedItem);
|
|
if (SelectNextInput())
|
|
return true;
|
|
}
|
|
else if (keyData == Keys.Left && this.ArrowNavigationEnabled ||
|
|
(keyData & Keys.Tab) == Keys.Tab && (keyData & Keys.Shift) == Keys.Shift && this.TabNavigationEnabled)
|
|
{
|
|
ValidateInput(this.FocusedItem);
|
|
if (SelectPreviousInput())
|
|
return true;
|
|
}
|
|
|
|
return base.OnCmdKey(ref msg, keyData);
|
|
}
|
|
|
|
private bool _TabNavigationEnabled = true;
|
|
/// <summary>
|
|
/// Gets or sets whether Tab key is used to navigate between the fields. Default value is true.
|
|
/// </summary>
|
|
[DefaultValue(true)]
|
|
public bool TabNavigationEnabled
|
|
{
|
|
get
|
|
{
|
|
return _TabNavigationEnabled;
|
|
}
|
|
set
|
|
{
|
|
_TabNavigationEnabled = value;
|
|
}
|
|
}
|
|
|
|
private bool _EnterNavigationEnabled = true;
|
|
/// <summary>
|
|
/// Gets or sets whether Enter key is used to navigate between input fields. Default value is true.
|
|
/// </summary>
|
|
[DefaultValue(true)]
|
|
public bool EnterNavigationEnabled
|
|
{
|
|
get
|
|
{
|
|
return _EnterNavigationEnabled;
|
|
}
|
|
set
|
|
{
|
|
_EnterNavigationEnabled = value;
|
|
}
|
|
}
|
|
|
|
private bool _ArrowNavigationEnabled = true;
|
|
/// <summary>
|
|
/// Gets or sets whether Arrow keys are used to navigate between input fields. Default value is true.
|
|
/// </summary>
|
|
[DefaultValue(true)]
|
|
public bool ArrowNavigationEnabled
|
|
{
|
|
get
|
|
{
|
|
return _ArrowNavigationEnabled;
|
|
}
|
|
set
|
|
{
|
|
_ArrowNavigationEnabled = value;
|
|
}
|
|
}
|
|
|
|
private bool _AutoAdvance = false;
|
|
/// <summary>
|
|
/// Gets or sets whether input focus is automatically advanced to next input field when input is complete in current one.
|
|
/// </summary>
|
|
[DefaultValue(false)]
|
|
public bool AutoAdvance
|
|
{
|
|
get { return _AutoAdvance; }
|
|
set { _AutoAdvance = value; }
|
|
}
|
|
|
|
protected override void OnInputComplete()
|
|
{
|
|
if (ValidateInput(this.FocusedItem))
|
|
{
|
|
if (_AutoAdvance)
|
|
{
|
|
if (!this.SelectNextInput())
|
|
{
|
|
OnGroupInputComplete();
|
|
}
|
|
}
|
|
}
|
|
|
|
base.OnInputComplete();
|
|
}
|
|
|
|
protected virtual bool ValidateInput(VisualItem inputItem)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
protected virtual void OnGroupInputComplete()
|
|
{
|
|
if (this.Parent != null)
|
|
{
|
|
this.Parent.ProcessInputComplete();
|
|
}
|
|
}
|
|
|
|
internal bool SelectNextInput()
|
|
{
|
|
return SelectInputItem(true);
|
|
}
|
|
|
|
internal bool SelectPreviousInput()
|
|
{
|
|
return SelectInputItem(false);
|
|
}
|
|
|
|
internal bool SelectInputItem(bool moveForward)
|
|
{
|
|
if (this.FocusedItem is VisualInputGroup)
|
|
{
|
|
VisualInputGroup group = this.FocusedItem as VisualInputGroup;
|
|
if (group.SelectInputItem(moveForward))
|
|
return true;
|
|
}
|
|
|
|
VisualCollectionEnumerator enumerator = new VisualCollectionEnumerator(this.Items, !moveForward || this.IsRightToLeft);
|
|
enumerator.CurrentIndex = this.Items.IndexOf(this.FocusedItem);
|
|
|
|
while (enumerator.MoveNext())
|
|
{
|
|
VisualInputBase vi = enumerator.Current as VisualInputBase;
|
|
if (vi != null && CanFocus(vi))
|
|
{
|
|
this.FocusedItem = vi;
|
|
return true;
|
|
}
|
|
else if (enumerator.Current is VisualInputGroup)
|
|
{
|
|
VisualInputGroup group = enumerator.Current as VisualInputGroup;
|
|
if (group.SelectInputItem(moveForward))
|
|
{
|
|
this.FocusedItem = group;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
protected override void OnGroupFocused()
|
|
{
|
|
if (this.FocusedItem == null)
|
|
SelectInputItem(true);
|
|
}
|
|
|
|
private bool _IsReadOnly = false;
|
|
/// <summary>
|
|
/// Gets or sets whether input items are read-only.
|
|
/// </summary>
|
|
public bool IsReadOnly
|
|
{
|
|
get { return _IsReadOnly; }
|
|
set
|
|
{
|
|
if (_IsReadOnly != value)
|
|
{
|
|
_IsReadOnly = value;
|
|
OnIsReadOnlyChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnIsReadOnlyChanged()
|
|
{
|
|
for (int i = 0; i < this.Items.Count; i++)
|
|
{
|
|
VisualInputBase v = this.Items[i] as VisualInputBase;
|
|
if (v != null) v.IsReadOnly = this.IsReadOnly;
|
|
}
|
|
}
|
|
|
|
protected override void OnItemsCollectionChanged(CollectionChangedInfo collectionChangedInfo)
|
|
{
|
|
if (collectionChangedInfo.ChangeType == eCollectionChangeType.Adding || collectionChangedInfo.ChangeType == eCollectionChangeType.Removing ||
|
|
collectionChangedInfo.ChangeType == eCollectionChangeType.Clearing)
|
|
{
|
|
if (collectionChangedInfo.Added != null)
|
|
{
|
|
foreach (VisualItem item in collectionChangedInfo.Added)
|
|
{
|
|
VisualInputBase v = item as VisualInputBase;
|
|
if (v != null)
|
|
{
|
|
v.IsReadOnly = this.IsReadOnly;
|
|
v.AutoOverwrite = _AutoOverwrite;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
base.OnItemsCollectionChanged(collectionChangedInfo);
|
|
}
|
|
|
|
private bool _AllowEmptyState = true;
|
|
[DefaultValue(true)]
|
|
public bool AllowEmptyState
|
|
{
|
|
get { return _AllowEmptyState; }
|
|
set
|
|
{
|
|
if (_AllowEmptyState != value)
|
|
{
|
|
_AllowEmptyState = value;
|
|
OnAllowEmptyStateChanged();
|
|
InvalidateArrange();
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual void OnAllowEmptyStateChanged()
|
|
{
|
|
foreach (VisualItem item in this.Items)
|
|
{
|
|
if (item is VisualNumericInput) ((VisualNumericInput)item).AllowEmptyState = this.AllowEmptyState;
|
|
}
|
|
}
|
|
|
|
private bool _IsEmpty = true;
|
|
/// <summary>
|
|
/// Gets or sets whether input group is empty i.e. it does not hold any value.
|
|
/// </summary>
|
|
[DefaultValue(true), Browsable(false)]
|
|
public bool IsEmpty
|
|
{
|
|
get { return _IsEmpty; }
|
|
set
|
|
{
|
|
if (_IsEmpty != value)
|
|
{
|
|
_IsEmpty = value;
|
|
if (_IsEmpty)
|
|
{
|
|
ResetValue();
|
|
}
|
|
if (this.Parent is VisualInputGroup)
|
|
((VisualInputGroup)this.Parent).UpdateIsEmpty();
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void OnInputChanged(VisualInputBase input)
|
|
{
|
|
UpdateIsEmpty();
|
|
base.OnInputChanged(input);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the IsEmpty property value based on the contained input controls.
|
|
/// </summary>
|
|
public virtual void UpdateIsEmpty()
|
|
{
|
|
bool empty = true;
|
|
foreach (VisualItem item in this.Items)
|
|
{
|
|
if (item is VisualInputBase && !((VisualInputBase)item).IsEmpty)
|
|
{
|
|
empty = false;
|
|
break;
|
|
}
|
|
else if (item is VisualInputGroup && !((VisualInputGroup)item).IsEmpty)
|
|
{
|
|
empty = false;
|
|
break;
|
|
}
|
|
|
|
}
|
|
this.IsEmpty = empty;
|
|
}
|
|
|
|
private bool _ResettingValue = false;
|
|
protected virtual void ResetValue()
|
|
{
|
|
_ResettingValue = true;
|
|
|
|
try
|
|
{
|
|
VisualItem[] items = new VisualItem[this.Items.Count];
|
|
this.Items.CopyTo(items);
|
|
foreach (VisualItem item in items)
|
|
{
|
|
if (item is VisualInputGroup)
|
|
((VisualInputGroup)item).IsEmpty = true;
|
|
else if (item is VisualInputBase)
|
|
((VisualInputBase)item).IsEmpty = true;
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
_ResettingValue = false;
|
|
}
|
|
}
|
|
|
|
private bool _AutoOverwrite = true;
|
|
/// <summary>
|
|
/// Gets or sets whether auto-overwrite functionality for input is enabled. When in auto-overwrite mode input field will erase existing entry
|
|
/// and start new one if typing is continued after InputComplete method is called.
|
|
/// </summary>
|
|
public bool AutoOverwrite
|
|
{
|
|
get { return _AutoOverwrite; }
|
|
set
|
|
{
|
|
if (_AutoOverwrite != value)
|
|
{
|
|
_AutoOverwrite = value;
|
|
OnAutoOverwriteChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnAutoOverwriteChanged()
|
|
{
|
|
foreach (VisualItem item in this.Items)
|
|
{
|
|
VisualInputBase input = item as VisualInputBase;
|
|
if (input != null && input.AutoOverwrite != _AutoOverwrite)
|
|
input.AutoOverwrite = _AutoOverwrite;
|
|
}
|
|
}
|
|
|
|
private bool _IsUserInput = false;
|
|
/// <summary>
|
|
/// Gets or sets whether current input is the user input.
|
|
/// </summary>
|
|
public bool IsUserInput
|
|
{
|
|
get { return _IsUserInput; }
|
|
set
|
|
{
|
|
_IsUserInput = value;
|
|
}
|
|
}
|
|
|
|
private string _SelectNextInputCharacters = "";
|
|
/// <summary>
|
|
/// List of characters that when pressed would select next input field.
|
|
/// </summary>
|
|
public string SelectNextInputCharacters
|
|
{
|
|
get { return _SelectNextInputCharacters; }
|
|
set
|
|
{
|
|
if (value == null) value = "";
|
|
if (_SelectNextInputCharacters != value)
|
|
{
|
|
_SelectNextInputCharacters = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void OnKeyPress(System.Windows.Forms.KeyPressEventArgs e)
|
|
{
|
|
if (_SelectNextInputCharacters.Length > 0 && _SelectNextInputCharacters.Contains(e.KeyChar.ToString()))
|
|
{
|
|
if (SelectNextInput())
|
|
{
|
|
e.Handled = true;
|
|
return;
|
|
}
|
|
}
|
|
base.OnKeyPress(e);
|
|
}
|
|
#endregion
|
|
|
|
}
|
|
}
|
|
#endif
|
|
|