/// <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 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); } }