|
C# Form |
|
This is a simple form sample that attempts to demonstrate many of the operations you may use in developing an interactive client application.
using System; using System.Timers; using System.Text; using System.Drawing; using System.Collections; using System.Windows.Forms; using System.Data; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using IDN.IO;
namespace WinFormsExample { public class Form1 : System.Windows.Forms.Form { // -------------------------------------------------------------------- TagServer m_tagServer = null; // The Tag Server. IOSchedule m_schedule = null; // Current schedule. IOTag m_tag = null; // Current tag. string m_fileName = "default.qd"; // Default filename.
// Used for displaying information in the textboxes. ArrayList m_tagEventLines = new ArrayList(100); ArrayList m_scheduleEventLines = new ArrayList(100); ArrayList m_outputLines = new ArrayList(100);
private System.Windows.Forms.Button m_getTagButton; private System.Windows.Forms.TextBox m_tagEventTextBox; private System.Windows.Forms.TextBox m_outputTextBox; private System.Windows.Forms.Button m_getScheduleButton; private System.Windows.Forms.TextBox m_scheduleEventTextBox; private System.Windows.Forms.OpenFileDialog m_openFileDialog; private System.Windows.Forms.SaveFileDialog m_saveFileDialog; private System.Windows.Forms.Button m_tagPropertiesButton; private System.Windows.Forms.Button m_schedulePropertiesButton; private System.Windows.Forms.Button m_tagSubscribeButton; private System.Windows.Forms.Button m_tagUnsubscribeButton; private System.Windows.Forms.Button m_scheduleSubscribeButton; private System.Windows.Forms.Button m_scheduleUnsubscribeButton; private System.Windows.Forms.Button m_tagWriteButton; private System.Windows.Forms.MainMenu m_mainMenu; private System.Windows.Forms.MenuItem menuItem1; private System.Windows.Forms.MenuItem menuItem2; private System.Windows.Forms.MenuItem m_newMenuItem; private System.Windows.Forms.MenuItem m_openMenuItem; private System.Windows.Forms.MenuItem m_saveMenuItem; private System.Windows.Forms.MenuItem m_saveAsMenuItem; private System.Windows.Forms.MenuItem m_exitMenuItem; private System.Windows.Forms.MenuItem m_tagServerMenuItem; private System.Windows.Forms.GroupBox m_outputGroupBox; private System.Windows.Forms.GroupBox m_tagGroupBox; private System.Windows.Forms.GroupBox m_scheduleGroupBox;
// -------------------------------------------------------------------- public Form1() { InitializeComponent(); }
// -------------------------------------------------------------------- #region Windows Form Designer generated code // removed ... #endregion
// -------------------------------------------------------------------- [STAThread] static void Main() { Application.Run(new Form1()); }
// -------------------------------------------------------------------- // private void OnFormLoad(object sender, System.EventArgs e) { // Create a Tag Server. m_tagServer = new TagServer();
// Clean now. m_tagServer.Dirty = false;
// Sign up for any error events from the IO. m_tagServer.Errored += new ErroredDelegate(OnIOErroredEventHandler); }
// -------------------------------------------------------------------- // Let the user select servers, create or edit schedules and tags to // be monitored. private void OnTagServerMenuItemClick(object sender, System.EventArgs e) { if (m_tagServer != null) m_tagServer.ShowDialog();
// We can do this because the server objects ignore duplicte // event handlers. SubscribeToAllPropertyChangedEvents(m_tagServer); }
// --------------------------------------------------------------------- // Demonstrate how to select a tag from the Tag Server and subscribe and // and unsubscribe from its Updated event. private void OnGetTagClick(object sender, System.EventArgs e) { if (m_tagServer != null) { // Let the user browse the configured IOTag's and select one. IOTag tag = (IOTag) m_tagServer.SelectItem(typeof(IOTag));
// Was a new tag was selected by the user? if (tag != null) { // If we already had one running in our example UI // then unsubscribe from the old tag's events. if ((m_tag != null)) m_tag.Updated -= new UpdatedDelegate(OnTagUpdatedEventHandler);
// This is now our new selected tag. m_tag = tag;
// Subscribe to the tag's Updated event. m_tag.Updated += new UpdatedDelegate(OnTagUpdatedEventHandler);
// Change the tag GroupBox text to the tag name. m_tagGroupBox.Text = m_tag.Name; } } }
// -------------------------------------------------------------------- // This event comes from the tag so 'sender' can be cast to an IOTag. // Check the type before casting in a real application. public void OnTagUpdatedEventHandler(object sender, UpdateEventArgs e) { try { // Use a StringBuilder for better speed. StringBuilder sb = new StringBuilder();
// Is the tag an array? if (e.Sample.Value.GetType().IsArray) { // Display the array values on a line. System.Array val = (System.Array) e.Sample.Value; for (int i = 0; i < val.Length; i++) { sb.AppendFormat("{0}, ", val.GetValue(i)); }
// Get rid of that last comma separator so it looks good and add a LF. if (sb.Length >= 2) sb.Length = sb.Length -2; sb.Append("\r\n"); WriteTagTextBox(sb.ToString());
// Display the timestamp and quality. sb.Length = 0; sb.AppendFormat("{0:MM/dd/yyyy, hh:mm:ss}:\t{1}", e.Sample.TimeStamp, e.Sample.Quality); WriteTagTextBox(sb.ToString()); } else { // Not an array so it's much easier. sb.AppendFormat("{0}:\t{1:MM/dd/yyyy, hh:mm:ss}:\t{2}", e.Sample.Value, e.Sample.TimeStamp, e.Sample.Quality); WriteTagTextBox(sb.ToString()); } } catch (Exception ex) { WriteOutputTextBox("Error updating tag: " + ex.Message); } }
// -------------------------------------------------------------------- // Demonstrate using an object's ShowDialog() method for editing properties. private void OnTagPropertiesClick(object sender, System.EventArgs e) { if (m_tag != null) m_tag.ShowDialog(); else WriteOutputTextBox("No current tag exist. Try selecting a tag first."); }
// -------------------------------------------------------------------- // Demonstrate using a tag's Write() method, using dialogs. private void OnTagWriteClick(object sender, System.EventArgs e) { if (m_tag != null) WriteOutputTextBox(m_tag.Write().ToString()); else WriteOutputTextBox("No current tag exists. Try selecting a tag first."); }
// -------------------------------------------------------------------- // Start listening to UpdatedEvents. Duplicate assignments are ignored. private void OnTagSubscribeClick(object sender, System.EventArgs e) { if (m_tag != null) m_tag.Updated += new UpdatedDelegate(OnTagUpdatedEventHandler); else WriteOutputTextBox("No current tag exists. Try Configuring servers then Selecting a tag first."); }
// -------------------------------------------------------------------- // Stop listening to UpdatedEvents. Duplicates are ignored. private void OnTagUnsubscribeClick(object sender, System.EventArgs e) { if (m_tag != null) m_tag.Updated -= new UpdatedDelegate(OnTagUpdatedEventHandler); else WriteOutputTextBox("No current tag exists. Try Configuring servers then Selecting a tag first."); }
// -------------------------------------------------------------------- // Let the user select a schedule to monitor. private void OnGetScheduleClick(object sender, System.EventArgs e) { if (m_tagServer != null) { // Use the provided UI to pick a schedule. IOSchedule schedule = (IOSchedule) m_tagServer.SelectItem(typeof(IOSchedule));
// Was a new schedule was selected by the user? if (schedule != null) { // If we already had one running if ((m_schedule != null)) m_schedule.Updated -= new UpdatedDelegate(OnScheduleUpdatedEventHandler);
// This is now our new current schedule. m_schedule = schedule;
// Subscribe to the events. m_schedule.Updated += new UpdatedDelegate(OnScheduleUpdatedEventHandler);
// Change the schedule's GroupBox text to the schedule name? m_scheduleGroupBox.Text = m_schedule.Name; } } }
// ------------------------------------------------------------------------ // Handle schedule Updated events. The schedule has an UpdatedTags list. // Get the tag values directly from the IOTag objects. private void OnScheduleUpdatedEventHandler(object sender, UpdateEventArgs e) { try { // Use a StringBuilder for better speed. StringBuilder sb = new StringBuilder();
// Scan and display the list of tags that changed. WriteScheduleTextBox(""); for (int i = 0; i < ((IOSchedule) sender).UpdatedTags.Count; i++) { // Array values are not processed here for simplicity. // Look at the tag Updated handler for an array example. IOTag tag = (IOTag) ((IOSchedule) sender).UpdatedTags.GetByIndex(i); sb.Length = 0; sb.AppendFormat("{0}:\t{1}:\t{2:MM/dd/yyyy, hh:mm:ss}:\t{3}", tag.Name, tag.Value, tag.TimeStamp, tag.Quality); WriteScheduleTextBox(sb.ToString()); } } catch (Exception ex) { WriteOutputTextBox("Error updating schedule: " + ex.Message); } }
// -------------------------------------------------------------------- // Demonstrate using an object's ShowDialog() method for editing properties. private void OnSchedulePropertiesClick(object sender, System.EventArgs e) { if (m_schedule != null) m_schedule.ShowDialog(); else WriteOutputTextBox("No current schedule exist. Try selecting a schedule first."); }
// -------------------------------------------------------------------- // Susbscribe to the schedule Updated event. private void OnScheduleSubscribeClick(object sender, System.EventArgs e) { if (m_schedule != null) m_schedule.Updated += new UpdatedDelegate(OnScheduleUpdatedEventHandler); else WriteOutputTextBox("No current schedule exists. Try Configuring servers then Selecting a schedule first."); }
// -------------------------------------------------------------------- // Unsubscribe from the schedule Updated event. private void OnScheduleUnsubscribeClick(object sender, System.EventArgs e) { if (m_schedule != null) m_schedule.Updated -= new UpdatedDelegate(OnScheduleUpdatedEventHandler); else WriteOutputTextBox("No current schedule exists. Try Configuring servers then Selecting a schedule first."); }
// ------------------------------------------------------------------------ // Handle PropertyChanged events for all of the Tag Server's objects. public void OnPropertyChangedEventHandler(object sender, IDN.IO.PropertyChangedEventArgs e) { try { // Display the sender's name. WriteOutputTextBox("\r\nProperty changed event from: " + ((IDNBrowsable) sender).Name);
// Loop through and display any changed property's name and value. IEnumerator ke = e.Properties.Keys.GetEnumerator(); IEnumerator ve = e.Properties.Values.GetEnumerator(); ke.MoveNext(); ve.MoveNext(); for(int i = 0; i < e.Properties.Count; i++) { WriteOutputTextBox(ke.Current.ToString() + ": " + ve.Current.ToString()); ke.MoveNext(); ve.MoveNext(); }
// This is how to specifically detect watchdog failure. if (sender.GetType() == typeof(IOServer)) { if (e.Properties.Contains("Mode")) { if(((ServerMode) e.Properties["Mode"]) == ServerMode.StatusCheckFailure) { WriteOutputTextBox("Watchdog status check failure."); } } } } catch (Exception ex) { WriteOutputTextBox("Error on PropertyChanged event: " + ex.Message); } }
// -------------------------------------------------------------------- // Handle error message events. public void OnIOErroredEventHandler(object sender, IDN.IO.ErroredEventArgs e) { if ((e.Sender != null) && (e.Sender.GetType().IsSubclassOf(typeof(IDNBrowsable)))) WriteOutputTextBox(e.Severity.ToString()+": "+e.Timestamp.ToString()+": "+((IDNBrowsable) e.Sender).Name+" "+e.Message); else WriteOutputTextBox(e.Severity.ToString()+": "+e.Timestamp.ToString()+" "+e.Message); }
// -------------------------------------------------------------------- // Recursive method to scan the entire Tag Server data tree and to direct // ALL PropertyChanged events to our one handler. "Node" in this case // refers to a data tree node. private void SubscribeToAllPropertyChangedEvents(IDNBrowsable inNode) { inNode.PropertyChanged += new PropertyChangedDelegate(OnPropertyChangedEventHandler); if (inNode.Children.Count > 0) { for (int i = 0; i < inNode.Children.Count; i++) { SubscribeToAllPropertyChangedEvents((IDNBrowsable) inNode.Children.GetByIndex(i)); } } }
// -------------------------------------------------------------------- // Save the Tag Server configuration to the current file. private void OnSaveMenuItemClick(object sender, System.EventArgs e) { if (m_tagServer != null) { // Ever been saved yet? if (m_fileName == "default.qd") { OnSaveAsMenuItemClick(sender, e); } else { Stream stream = File.Open(m_fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None); if (stream != null) { BinaryFormatter formatter = new BinaryFormatter();
// This is all that is needed to save the contents of the // IO configuration onto the stream. formatter.Serialize(stream, m_tagServer); stream.Close(); }
// This clears the dirty flag for ALL items in the Tag Server. m_tagServer.Dirty = false; } } }
// -------------------------------------------------------------------- // Save the Tag Server configuration to a user selected file. private void OnSaveAsMenuItemClick(object sender, System.EventArgs e) { if (m_tagServer != null) { m_saveFileDialog.FileName = m_fileName; if (m_saveFileDialog.ShowDialog(this) == DialogResult.OK) { Stream stream = null; if ((stream = m_saveFileDialog.OpenFile()) != null) { m_fileName = m_saveFileDialog.FileName; BinaryFormatter formatter = new BinaryFormatter();
// Serialize the complete IO configuration onto the stream formatter.Serialize(stream, m_tagServer); stream.Close(); }
// Clear all of the Tag Server objects' dirty flags. m_tagServer.Dirty = false; } } }
// -------------------------------------------------------------------- // Open a Tag Server configuration. private void OnOpenMenuItemClick(object sender, System.EventArgs e) { // Make sure we have a Tag Server object. if (m_tagServer != null) { // Check for changes so we don't overwrite it with the new file contents. if (m_tagServer.Dirty) { // Prompt the user to save the changes before overwriting with the new configuration. if ( MessageBox.Show("Save Changes to: " + m_fileName + "?", "Save Changes", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { OnSaveMenuItemClick(sender, e); } } }
// Let the user select the file to open. if ( m_openFileDialog.ShowDialog(this) == DialogResult.OK) { Stream stream = null; if ((stream = m_openFileDialog.OpenFile()) != null) { m_fileName = m_openFileDialog.FileName; BinaryFormatter formatter = new BinaryFormatter();
// Release any existing Tag Server. m_tagServer.Release( |