/// <summary> /// Shows a detailed view for array values. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> //TODO make it visible after implementing complex values. private void m_CMS_View_Click(object sender, System.EventArgs e) { if (m_ItemListLV.SelectedItems.Count > 0) { ListViewItem listItem = m_ItemListLV.SelectedItems[0]; object tag = listItem.Tag; if (tag != null && tag.GetType() == typeof(OpcDa::ItemValueResult)) { OpcDa::ItemValueResult item = (OpcDa::ItemValueResult)tag; if (item.Value != null) { ComplexItem complexItem = ComplexTypeCache.GetComplexItem(item); if (complexItem != null) { EditComplexValueDlg dialog = (EditComplexValueDlg)m_viewers[listItem]; if (dialog == null) { m_viewers[listItem] = dialog = new EditComplexValueDlg(); dialog.Disposed += new System.EventHandler(OnViewerClosed); } dialog.ShowDialog(complexItem, item.Value, true, false); } else if (item.Value.GetType().IsArray) { new EditArrayDlg().ShowDialog(item.Value, true); } } } } }
/// <summary> /// Called when a subscription is added or removed from the control. /// </summary> public void OnSubscriptionModified(Subscription subscription, bool deleted) { if (subscription == null) { return; } if (!deleted) { // check if the subscription is already added to the control. if (m_items.Contains(subscription.ClientHandle)) { return; } // register for data updates. subscription.DataChanged += new OpcDa::DataChangedEventHandler(OnDataChange); subscription.DeleteSubscription += new System.EventHandler(subscription_DeleteSubscription); // add to subscription list. m_subscriptions.Add(subscription.ClientHandle, subscription); m_items.Add(subscription.ClientHandle, new ArrayList()); } else { // check if the subscription is already removed from the control. if (!m_items.Contains(subscription.ClientHandle)) { return; } // unregister for data updates. try { subscription.DataChanged -= new OpcDa::DataChangedEventHandler(OnDataChange); } catch (System.Exception) { //Now we can do nothig abou it } subscription.DeleteSubscription -= new System.EventHandler(subscription_DeleteSubscription); // remove all items for the subscription. ArrayList existingItemList = (ArrayList)m_items[subscription.ClientHandle]; foreach (ListViewItem listItem in existingItemList) { EditComplexValueDlg dialog = (EditComplexValueDlg)m_viewers[listItem]; if (dialog != null) { dialog.Close(); m_viewers.Remove(listItem); } listItem.Remove(); } // remove from subscription list. m_subscriptions.Remove(subscription.ClientHandle); m_items.Remove(subscription.ClientHandle); } }
/// <summary> /// Called when the edit array button is clicked. /// </summary> private void EditBTN_Click(object sender, System.EventArgs e) { try { object value = null; ComplexItem complexItem = ComplexTypeCache.GetComplexItem(m_itemID); if (complexItem != null) { value = new EditComplexValueDlg().ShowDialog(complexItem, m_value, m_readOnly, true); } else if (m_value.GetType().IsArray) { value = new EditArrayDlg().ShowDialog(m_value, m_readOnly); } if (m_readOnly || value == null) { return; } // update the array. Set(value, m_readOnly); // send change notification. if (ValueChanged != null) { ValueChanged(this, m_value); } } catch (System.Exception exception) { MessageBox.Show(exception.Message); } }
/// <summary> /// Adds an item to the list view. /// </summary> /// <param name="subscriptionHandle">The subscription handle.</param> /// <param name="item">The item.</param> /// <param name="replaceableItem">The replaceable item.</param> private void AddValue(object subscriptionHandle, OpcDa::ItemValueResult item, ref ListViewItem replaceableItem) { string quality = ""; // format quality. if (item.QualitySpecified) { quality += item.Quality.QualityBits.ToString(); if (item.Quality.LimitBits != OpcDa::limitBits.none) { quality += ", "; quality += item.Quality.LimitBits.ToString(); } if (item.Quality.VendorBits != 0) { quality += System.String.Format(", {0:X}", item.Quality.VendorBits); } } // format columns. string[] columns = new string[] { item.ItemName, item.ItemPath, Opc.Convert.ToString(item.Value), (item.Value != null)?Opc.Convert.ToString(item.Value.GetType()):"", quality, (item.TimestampSpecified)?Opc.Convert.ToString(item.Timestamp):"", GetErrorText(subscriptionHandle, item.ResultID) }; // update an existing item. if (replaceableItem != null) { for (int ii = 0; ii < replaceableItem.SubItems.Count; ii++) { replaceableItem.SubItems[ii].Text = columns[ii]; } replaceableItem.Tag = item; replaceableItem.ForeColor = Color.Empty; // update detail view dialog. EditComplexValueDlg dialog = (EditComplexValueDlg)m_viewers[replaceableItem]; if (dialog != null) { dialog.UpdateValue(item.Value); } return; } // create a new list view item. replaceableItem = new ListViewItem(columns, (int)ImageListLibrary.Icons.IMAGE_TAG); replaceableItem.Tag = item; // insert after any existing item value with the same client handle. for (int ii = m_ItemListLV.Items.Count - 1; ii >= 0; ii--) { OpcDa::ItemValueResult previous = (OpcDa::ItemValueResult)m_ItemListLV.Items[ii].Tag; if (previous.ClientHandle != null && previous.ClientHandle.Equals(item.ClientHandle)) { m_ItemListLV.Items.Insert(ii + 1, replaceableItem); return; } } m_ItemListLV.Items.Add(replaceableItem); }
/// <summary> /// Called when a data update event is raised by a subscription. /// </summary> private void OnDataChange(object subscriptionHandle, object requestHandle, OpcDa::ItemValueResult[] values) { // ensure processing is done on the control's main thread. if (InvokeRequired) { BeginInvoke(new OpcDa::DataChangedEventHandler(OnDataChange), new object[] { subscriptionHandle, requestHandle, values }); return; } try { // find subscription. ArrayList existingItemList = (ArrayList)m_items[subscriptionHandle]; // check if subscription is still valid. if (existingItemList == null) { return; } // change all existing item values for the subscription to 'grey'. // this indicates an update arrived but the value did not change. foreach (ListViewItem listItem in existingItemList) { if (listItem.ForeColor != Color.Gray) { listItem.ForeColor = Color.Gray; } } // do nothing more if only a keep alive callback. if (values == null || values.Length == 0) { OnKeepAlive(subscriptionHandle); return; } if (UpdateEvent != null) { UpdateEvent(subscriptionHandle, values); } // update list view. ArrayList newListItems = new ArrayList(); foreach (OpcDa::ItemValueResult value in values) { // item value should never have a null client handle. if (value.ClientHandle == null) { continue; } // this item can be updated with new values instead of inserting/removing items. ListViewItem replacableItem = null; // remove existing items. if (!m_CMS_KeepValues.Checked) { // search list of existing items for previous values for this item. ArrayList updatedItemList = new ArrayList(existingItemList.Count); foreach (ListViewItem listItem in existingItemList) { OpcDa::ItemValueResult previous = (OpcDa::ItemValueResult)listItem.Tag; if (!value.ClientHandle.Equals(previous.ClientHandle)) { updatedItemList.Add(listItem); continue; } if (replacableItem != null) { EditComplexValueDlg dialog = (EditComplexValueDlg)m_viewers[replacableItem]; if (dialog != null) { dialog.Close(); m_viewers.Remove(replacableItem); } replacableItem.Remove(); } replacableItem = listItem; } // the updated list has all values for the current item removed. existingItemList = updatedItemList; } // add value to list. AddValue(subscriptionHandle, value, ref replacableItem); // save new list item. if (replacableItem != null) { newListItems.Add(replacableItem); } } // add new items to existing item list. existingItemList.AddRange(newListItems); m_items[subscriptionHandle] = existingItemList; // adjust column widths. for (int ii = 0; ii < m_ItemListLV.Columns.Count; ii++) { if (ii != VALUE && ii != QUALITY) { m_ItemListLV.Columns[ii].Width = -2; } } } catch (System.Exception e) { OnException(subscriptionHandle, e); } }