2017年9月28日 星期四

C# ObservableCollection 此類型的 CollectionView 不支援從 與發送器執行續不同的執行緒變更其SourceCollection

今天撰寫OPC Server遇到一個問題是 我的OPCServerSource已經跟UI的TreeView綁定了 可是我又透過OPC Client去取得Browser的Server的資料 再要將Server資料匯入到OPCServerSource時,出現如圖下的錯誤。



解決的方法是在要匯入的地方加入Application.Current.Dispatcher.BeginInvoke((Action)delegate () {};這行,就可以解決問題了

private void ServerBrowserItemsUI(List serverList)
{
  Application.Current.Dispatcher.BeginInvoke((Action)delegate ()
  {
    serverList.ToList().ForEach(args =>
    {
    OPCServerSource.Add(new Model.OPCServer() { ProgName = args.progID, ProgID = args.clsid.ToString(), Url = new System.Windows.Media.Imaging.BitmapImage(new Uri(@"/OPCDASettingWPFLib;component/Common/Images/lightIcon_green_20.png", UriKind.RelativeOrAbsolute)) });
    });
  });
}

2017年9月17日 星期日

混合模式組件是針對版本 v2.0.50727 的執行階段建置的,無法在沒有其他組態資訊的情況下載入 4.0 執行階段中。

小編今天撰寫OPC Server時,套用的Third Party是.NET Framework 2.0的版本 而公司採用的是.NET Framework 4.0的版本,所以出現了以下的錯誤。



根據網路上解決的方法是在App.Config裡面加入『useLegacyV2RuntimeActivationPolicy="true"』這行即可。



     
        
    



2017年9月14日 星期四

C# DateTime To SQL Server DateTime

C# Function

        public bool WriteAlarmEvent(IOPCDAClientLib.AlarmRecord alarm)
        {
            bool result = false;
            using (_cmd = new SqlCommand("AlarmRecordAdd", _connect))
            {
                _cmd.CommandType = System.Data.CommandType.StoredProcedure;
                _cmd.Parameters.Add("@TagName", System.Data.SqlDbType.NVarChar, 200);
                _cmd.Parameters.Add("@AlarmState", System.Data.SqlDbType.NVarChar, 100);
                _cmd.Parameters.Add("@Description", System.Data.SqlDbType.NVarChar);
                _cmd.Parameters.Add("@Value", System.Data.SqlDbType.NVarChar, 100);
                _cmd.Parameters.Add("@EventStampDate", System.Data.SqlDbType.Date);
                _cmd.Parameters.Add("@EventStampTime", System.Data.SqlDbType.Time);
                _cmd.Parameters.Add("@Provider", System.Data.SqlDbType.NVarChar, 100);
                _cmd.Parameters.Add("@Area", System.Data.SqlDbType.NVarChar, 100);
                _cmd.Parameters.Add("@Type", System.Data.SqlDbType.NVarChar, 100);
                _cmd.Parameters.Add("@Priority", System.Data.SqlDbType.Int,1);
                _cmd.Parameters.Add("@MilliSec", System.Data.SqlDbType.Int,1);
                _cmd.Parameters.Add("@Category", System.Data.SqlDbType.NVarChar, 100);
                _cmd.Parameters.Add("@CheckValue", System.Data.SqlDbType.NVarChar, 100);
                _cmd.Parameters.Add("@Operator", System.Data.SqlDbType.NVarChar, 100);
                _cmd.Parameters.Add("@DomainName", System.Data.SqlDbType.NVarChar, 100);
                _cmd.Parameters.Add("@UserFullName", System.Data.SqlDbType.NVarChar, 100);
                _cmd.Parameters.Add("@OperatorNode", System.Data.SqlDbType.NVarChar, 100);
                _cmd.Parameters.Add("@AlarmId", System.Data.SqlDbType.Int);

                _cmd.Parameters["@TagName"].Value = alarm.TagName ?? "";
                _cmd.Parameters["@AlarmState"].Value = alarm.AlarmState ?? "";
                _cmd.Parameters["@Description"].Value = alarm.Description ?? "";
                _cmd.Parameters["@Value"].Value = alarm.Value ?? "";
                _cmd.Parameters["@EventStampDate"].Value = DateTime.Now.ToString("yyyy/MM/dd");
                _cmd.Parameters["@EventStampTime"].Value = DateTime.Now.ToString("HH:mm:ss.fff");
                _cmd.Parameters["@Provider"].Value = alarm.Provider ?? "";
                _cmd.Parameters["@Area"].Value = alarm.Area ?? "";
                _cmd.Parameters["@Type"].Value = alarm.Type ?? "";
                _cmd.Parameters["@Priority"].Value = alarm.Priority;
                _cmd.Parameters["@MilliSec"].Value = 0;
                _cmd.Parameters["@Category"].Value = alarm.Category ?? "";
                _cmd.Parameters["@CheckValue"].Value = alarm.CheckValue;
                _cmd.Parameters["@Operator"].Value = alarm.Operator ?? "";
                _cmd.Parameters["@DomainName"].Value = alarm.DomainName ?? "";
                _cmd.Parameters["@UserFullName"].Value = alarm.UserFullName ?? "";
                _cmd.Parameters["@OperatorNode"].Value = alarm.OperatorNode ?? "";
                _cmd.Parameters["@AlarmId"].Value = alarm.AlarmId;
                _connect.Open();
                try
                {
                    if(ConnectStatus())
                    {
                        _cmd.ExecuteNonQuery();
                        _connect.Close();
                        result = true;
                    }
                    else
                    {
                        result = false;
                    }

                }
                catch(Exception ex)
                {
                    result = false;
                    throw ex;
                }
                finally
                {
                    _connect.Close();
                }
            }
            return result;
        }


SQL Stored Prodceduce
ALTER PROCEDURE [dbo].[AlarmRecordAdd]
    @TagName nvarchar(200), @AlarmState nvarchar(100), @Description nvarchar(MAX),
    @Value nvarchar(100), @EventStampDate datetime, @EventStampTime datetime,
    @Provider nvarchar(100), @Area nvarchar(100), @Type nvarchar(100), @Priority int,
    @MilliSec int, @Category nvarchar(100), @CheckValue nvarchar(100), @Operator nvarchar(100),
    @DomainName nvarchar(100), @UserFullName nvarchar(100), @OperatorNode nvarchar(100),
    @AlarmId int
AS
 
DECLARE @EventTimeStamp datetime
DECLARE @EventDate char(10)
DECLARE @EventTime char(12)
 
BEGIN
    IF @EventStampDate IS NOT NULL AND @EventStampTime IS NOT NULL
    BEGIN
        SET @EventDate = CONVERT(varchar(10), @EventStampDate, 111)
        SET @EventTime = CONVERT(varchar(12), @EventStampTime, 114)
        SET @EventTimeStamp = CONVERT(datetime, @EventDate + ' ' + @EventTime, 121)
        SET @MilliSec = DATEPART(MS,@EventTimeStamp)
    END
    ELSE
    BEGIN
        SET @EventTimeStamp = '1900-01-01 07:07:07'
    END
    
    IF NOT EXISTS(SELECT TOP 1 EventStamp FROM AlarmRecord WHERE EventStamp = @EventTimeStamp AND TagName = @TagName AND AlarmState = @AlarmState )
    BEGIN
        INSERT INTO AlarmRecord(TagName, AlarmState, [Description], [Value], EventStamp,EventStampUTC, Provider, Area,
        [Type], Priority, MilliSec, Category, CheckValue, Operator, DomainName, UserFullName, OperatorNode,
        AlarmId, WriteTimestamp)
        VALUES(@TagName, @AlarmState, @Description, @Value, @EventTimeStamp,@EventTimeStamp, @Provider, @Area, @Type, @Priority,
        @MilliSec, @Category, @CheckValue, @Operator, @DomainName, @UserFullName, @OperatorNode, @AlarmId, GETDATE())
    END
    
    SELECT 0
END


執行結果



若要加入毫秒,則 DateTime.Now.ToString("HH:mm:ss.fff"); 要加在ss後面