using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; using System.Xml; using TradeIdeas.XML; namespace TradeIdeas.TIProGUI.CBT { public partial class ConfigDemoPercentUpDown : UserControl, IChild { static public void SaveAll() { foreach (XmlNode example in ConfigDemoUserControl.ConfigDemoXml.Node("CONFIG_DEMO_PERCENT_UP_DOWN").Enum()) { // This is not obvious at first. The the delegate referenced "example" directly, all // of the delegates would point to the last value in the example variable. By creating // this "savedCopy" variable, I am ensuring that each delegate points to the current // value in the example variable. XmlNode savedCopy = example; foreach (XmlNode node in example) { //some nodes have more than one filter code..loop thru these... if (node.SafeName() == "FILTER") { string filterCode = node.Property("CODE"); ConfigDemoUserControl.Add(filterCode, delegate(IContainer container) { return new ConfigDemoPercentUpDown(container, savedCopy); }); } } } } private readonly TradeIdeas.TIProGUI.CBT.IContainer _container; private readonly bool _limitRange; public ConfigDemoPercentUpDown(TradeIdeas.TIProGUI.CBT.IContainer container, XmlNode config) { _container = container; InitializeComponent(); container.MinTextBox.TextChanged += new EventHandler(MinTextBox_TextChanged); container.MaxTextBox.TextChanged += new EventHandler(MaxTextBox_TextChanged); string bottomDescription = config.PropertyForCulture("BOTTOM", "***"); string topDescription = config.PropertyForCulture("TOP", "***"); _limitRange = config.Property("LIMIT_RANGE", false); minUpFromBottomLabel.Text = "Min above " + bottomDescription; maxUpFromBottomLabel.Text = "Max above " + bottomDescription; minDownFromBottomLabel.Text = "Min below " + bottomDescription; maxDownFromBottomLabel.Text = "Max below " + bottomDescription; minUpFromTopLabel.Text = "Min above " + topDescription; maxUpFromTopLabel.Text = "Max above " + topDescription; minDownFromTopLabel.Text = "Min below " + topDescription; maxDownFromTopLabel.Text = "Max below " + topDescription; } void MinTextBox_TextChanged(object sender, EventArgs e) { _externalChangeInProgress = true; double? value = _container.MinValue; SafeSet(minUpFromBottomTextBox, value); SafeSet(maxDownFromBottomTextBox, -value); SafeSet(minUpFromTopTextBox, value - 100); SafeSet(maxDownFromTopTextBox, 100 - value); _externalChangeInProgress = false; CheckForError(); } void MaxTextBox_TextChanged(object sender, EventArgs e) { _externalChangeInProgress = true; double? value = _container.MaxValue; SafeSet(maxUpFromBottomTextBox, value); SafeSet(minDownFromBottomTextBox, -value); SafeSet(maxUpFromTopTextBox, value - 100); SafeSet(minDownFromTopTextBox, 100 - value); _externalChangeInProgress = false; CheckForError(); } private void SetColor(TextBox textBox, bool ok) { textBox.BackColor = ok ? SystemColors.Window : ConfigDemoUserControl.ERROR_BACKGROUND; } private void CheckForError() { if (!_limitRange) return; double? min = _container.MinValue; double? max = _container.MaxValue; bool minOk = (!min.HasValue) || (min.Value <= 100 && min.Value >= 0); bool maxOk = (!max.HasValue) || (max.Value <= 100 && max.Value >= 0); SetColor(minUpFromBottomTextBox, minOk); SetColor(maxDownFromBottomTextBox, minOk); SetColor(maxUpFromBottomTextBox, maxOk); SetColor(minDownFromBottomTextBox, maxOk); SetColor(minUpFromTopTextBox, minOk); SetColor(maxDownFromTopTextBox, minOk); SetColor(maxUpFromTopTextBox, maxOk); SetColor(minDownFromTopTextBox, maxOk); warningLabel.Visible = !(minOk && maxOk); } private string Displayable(double? value) { if (null == value) return ""; else return value.ToString(); } private void SafeSet(TextBox destination, double? value) { if (_startingFrom == destination) // No cycles. // If the user was typing here, leave exactly what he said, even if it makes no sense. return; destination.Text = Displayable(value); } /// /// Which of the text boxes on this UserControl started the change. /// This might be null if the change starte from somewhere else. /// private object _startingFrom; /// /// This is true if a callback from one the TextBoxes owned by the IContainer is in progress. /// private bool _externalChangeInProgress; private void SafeSet(object sender, bool max, double? value) { if (_externalChangeInProgress) return; _startingFrom = sender; TextBox destination = max ? _container.MaxTextBox : _container.MinTextBox; destination.Text = Displayable(value); _startingFrom = null; } private static double? GetValue(TextBox t) { double value; if (double.TryParse(t.Text, out value)) return value; else return null; } private void minUpFromBottomTextBox_TextChanged(object sender, EventArgs e) { SafeSet(sender, false, GetValue(minUpFromBottomTextBox)); } private void maxUpFromBottomTextBox_TextChanged(object sender, EventArgs e) { SafeSet(sender, true, GetValue(maxUpFromBottomTextBox)); } private void minDownFromBottomTextBox_TextChanged(object sender, EventArgs e) { SafeSet(sender, true, -GetValue(minDownFromBottomTextBox)); } private void maxDownFromBottomTextBox_TextChanged(object sender, EventArgs e) { SafeSet(sender, false, -GetValue(maxDownFromBottomTextBox)); } private void minUpFromTopTextBox_TextChanged(object sender, EventArgs e) { SafeSet(sender, false, 100 + GetValue(minUpFromTopTextBox)); } private void maxUpFromTopTextBox_TextChanged(object sender, EventArgs e) { SafeSet(sender, true, 100 + GetValue(maxUpFromTopTextBox)); } private void minDownFromTopTextBox_TextChanged(object sender, EventArgs e) { SafeSet(sender, true, 100 - GetValue(minDownFromTopTextBox)); } private void maxDownFromTopTextBox_TextChanged(object sender, EventArgs e) { SafeSet(sender, false, 100 - GetValue(maxDownFromTopTextBox)); } private void flipButton_Click(object sender, EventArgs e) { string minText = Displayable(100 - _container.MaxValue); string maxText = Displayable(100 - _container.MinValue); _container.MinTextBox.Text = minText; _container.MaxTextBox.Text = maxText; } string IChild.Name { get { return "Up vs. Down"; } } Control IChild.Body { get { return this; } } bool IChild.CanShowExample { get { return true; } } void IChild.OnShow() { } } }