250 lines
7.0 KiB
C#

#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
namespace DevComponents.Editors
{
public class IpAddressGroup : VisualInputGroup
{
#region Events
public event EventHandler ValueChanged;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the IPAddressGroup class.
/// </summary>
public IpAddressGroup()
{
// Create IP4 default items
for (int i = 0; i < 4; i++)
{
VisualIntegerInput input = new VisualIntegerInput();
input.MaxValue = 255;
input.MinValue = 0;
this.Items.Add(input);
if (i < 3)
{
VisualLabel label = new VisualLabel();
label.Text = ".";
this.Items.Add(label);
}
}
}
#endregion
#region Internal Implementation
private string _Value;
public string Value
{
get
{
if (this.IsFocused)
{
if (IsInputValid())
return GetCurrentInputValue();
}
return _Value;
}
set
{
bool valueChanged = _Value != value;
if (!string.IsNullOrEmpty(value))
{
if (!IsValueValid(value))
throw new ArgumentException("Value is not valid IP value");
}
_Value = value;
UpdateInputItems();
if(valueChanged)
OnValueChanged(EventArgs.Empty);
}
}
bool _UpdatingInputItems = false;
private void UpdateInputItems()
{
if (_UpdatingInputItems) return;
_UpdatingInputItems = true;
try
{
if (string.IsNullOrEmpty(_Value))
{
// Clear all input
for (int i = 0; i < this.Items.Count; i++)
{
if (this.Items[i] is VisualIntegerInput)
{
VisualIntegerInput input = this.Items[i] as VisualIntegerInput;
input.IsEmpty = true;
}
}
}
else
{
int[] value = ParseIPv4Value(_Value);
int index = 0;
for (int i = 0; i < this.Items.Count; i++)
{
if (this.Items[i] is VisualIntegerInput)
{
VisualIntegerInput input = this.Items[i] as VisualIntegerInput;
input.Value = value[index];
index++;
}
}
}
}
finally
{
_UpdatingInputItems = false;
}
}
private void OnValueChanged(EventArgs e)
{
EventHandler handler = ValueChanged;
if (handler != null) ValueChanged(this, e);
}
internal bool IsValueValid(string ipValue)
{
int[] value = ParseIPv4Value(ipValue);
return value != null;
}
private int[] ParseIPv4Value(string ipValue)
{
if (string.IsNullOrEmpty(ipValue)) return null;
string[] parts = ipValue.Split('.');
if (parts.Length != 4) return null;
int[] value = new int[4];
for (int i = 0; i < parts.Length; i++)
{
int partValue = 0;
if (int.TryParse(parts[i], out partValue))
{
if (partValue < 0 || partValue > 255) return null;
value[i] = partValue;
}
else return null;
}
return value;
}
private bool IsInputValid()
{
bool allEmpty = true;
for (int i = 0; i < this.Items.Count; i++)
{
VisualIntegerInput input = this.Items[i] as VisualIntegerInput;
if (input != null)
{
if (input.IsEmpty)
{
if (!allEmpty && AllowEmptyState) return false;
}
else
{
if (allEmpty && i > 0) return false;
allEmpty = false;
}
}
}
return true;
}
protected override void OnLostFocus()
{
UpdateValue();
base.OnLostFocus();
}
protected override void OnInputChanged(VisualInputBase input)
{
if (!_UpdatingInputItems && GetCurrentInputValue() != null)
{
_UpdatingInputItems = true; // Stop update of UI items
try
{
UpdateValue();
}
finally
{
_UpdatingInputItems = false;
}
}
base.OnInputChanged(input);
}
private string GetCurrentInputValue()
{
int[] value = new int[4];
int index = 0;
bool isInvalid = false;
for (int i = 0; i < this.Items.Count; i++)
{
VisualIntegerInput input = this.Items[i] as VisualIntegerInput;
if (input != null)
{
if (input.IsEmpty)
{
if (!this.AllowEmptyState)
value[index] = 0;
else
{
isInvalid = true;
break;
}
}
value[index] = input.Value;
index++;
}
}
if (isInvalid)
return null;
else
{
string s = "";
for (int i = 0; i < value.Length; i++)
{
s += value[i].ToString();
if (i < value.Length - 1)
s += ".";
}
return s;
}
}
private void UpdateValue()
{
Value = GetCurrentInputValue();
}
private bool _ResettingValue = false;
protected override void ResetValue()
{
_ResettingValue = true;
try
{
this.Value = null;
}
finally
{
_ResettingValue = false;
}
}
#endregion
}
}
#endif