C# 将新集合项推送到其他类中的GridView

C# 将新集合项推送到其他类中的GridView,c#,winforms,design-patterns,.net-3.5,C#,Winforms,Design Patterns,.net 3.5,我有一个LogOperations类,它是一个单例类,它包含我的Log对象的集合和一些向集合中添加新Log的方法日志只有3个属性消息,异常和时间 在我的应用程序中的唯一表单上,我得到了对登录操作的引用。然后我使用它的Collection logs属性从每个条目构建一个数据表,并将其放入GridControl(gdcErrorLogs)中 我还有一堆其他类,它们为表单执行各种各样的函数,每当这些函数捕捉到错误时,我就会将该错误写入我的LogOperations集合 如何使表单的网格在每次添加日志时

我有一个
LogOperations
类,它是一个单例类,它包含我的
Log
对象的集合和一些向集合中添加新
Log
的方法<代码>日志只有3个属性<代码>消息,
异常
时间

在我的应用程序中的唯一表单上,我得到了对
登录操作的引用。然后我使用它的
Collection logs
属性从每个条目构建一个数据表,并将其放入
GridControl
(gdcErrorLogs)中

我还有一堆其他类,它们为表单执行各种各样的函数,每当这些函数捕捉到错误时,我就会将该错误写入我的
LogOperations
集合

如何使表单的网格在每次添加
日志时自动更新此新条目?我正在考虑在我的
LogOperations
类中添加对表单的引用,然后在Add函数的末尾,我将表单的网格重新设置为这个新的数据表

public class AddNewLogEventArgs : EventArgs
{
    public Log log { get; private set; } // Error on compile see below
    public AddNewLogEventArgs(Log newLog) // Error on compile see below
    {
        log = newLog;
    }
}

class LogOps
{
    public delegate void AddNewLogHandler(object sender, AddNewLogEventArgs e);
    public event AddNewLogHandler OnAddNewLog;

    private Collection<Log> _logs;
    private static LogOps _singleton;

    private LogOps() 
    {
        _logs = new Collection<Log>();
    }

    public static LogOps Instance
    {
        get 
        {
            if (_singleton == null)
                _singleton = new LogOps();
            return _singleton;
        }
    }

    public void AddLog(string text)
    {
        Log newLog = new Log(text);
        _singleton._logs.Add(newLog);
        OnAddNewLog(new AddNewLogEventArgs(newLog), null);
    }

    public void AddLog(Log log)
    {
        Log newLog = log;
        _singleton._logs.Add(newLog);
        OnAddNewLog(new AddNewLogEventArgs(newLog), null);
    }

    public void AddLog(Exception ex)
    {
        Log newLog = new Log(ex.Message, ex.InnerException);
        _singleton._logs.Add(newLog);
        OnAddNewLog(new AddNewLogEventArgs(newLog), null);
    }

    public DataTable GetLogsAsDataTable()
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("Time");
        dt.Columns.Add("Error");
        dt.Columns.Add("Exception");

        int i = 0;
        foreach (Log log in _logs)
        {
            dt.Rows.Add();

            dt.Rows[i].SetField("Time", log.Time);
            dt.Rows[i].SetField("Error", log.Err);
            dt.Rows[i].SetField("Exception", log.Ex.Message);
            i++;
        }
        return dt;
    }
}
公共类AddNewLogEventArgs:EventArgs
{
公共日志日志{get;private set;}//编译时出错,请参见下文
public AddNewLogEventArgs(Log newLog)//编译时出错,请参见下文
{
log=newLog;
}
}
类标识
{
公共委托void AddNewLogHandler(对象发送方,AddNewLogEventArgs e);
公共事件AddNewLogHandler OnAddNewLog;
私人收藏日志;
私有静态登录_singleton;
私人LogOps()
{
_日志=新集合();
}
公共静态登录实例
{
得到
{
如果(_singleton==null)
_singleton=新LogOps();
返回单件;
}
}
公共void AddLog(字符串文本)
{
Log newLog=新日志(文本);
_singleton.\u logs.Add(newLog);
OnAddNewLog(newAddNewLogEventArgs(newLog),null);
}
公共无效添加日志(日志日志)
{
Log newLog=Log;
_singleton.\u logs.Add(newLog);
OnAddNewLog(newAddNewLogEventArgs(newLog),null);
}
公共无效添加日志(例外情况除外)
{
Log newLog=新日志(例如Message,例如InnerException);
_singleton.\u logs.Add(newLog);
OnAddNewLog(newAddNewLogEventArgs(newLog),null);
}
公共数据表GetLogsAsDataTable()
{
DataTable dt=新的DataTable();
dt.列。添加(“时间”);
dt.Columns.Add(“错误”);
dt.列。添加(“例外”);
int i=0;
foreach(登录日志)
{
dt.Rows.Add();
dt.Rows[i].SetField(“Time”,log.Time);
dt.Rows[i].SetField(“Error”,log.Err);
dt.Rows[i].SetField(“异常”,log.Ex.Message);
i++;
}
返回dt;
}
}
Edit自试用King的解决方案以来,代码示例被大量修改

AddNewLogEventArgs中的两个标记行显示以下两个错误:

  • 错误1可访问性不一致:属性类型“PrepareDeployment.Models.Log”的可访问性不如属性“PrepareDeployment.Processs.AddNewLogEventArgs.Log”
  • 错误2可访问性不一致:参数类型“PrepareDeployment.Models.Log”的可访问性不如方法“PrepareDeployment.Processs.AddNewLogEventArgs.AddNewLogEventArgs(PrepareDeployment.Models.Log)”的可访问性

    • 您应该这样做:

      public delegate void AddNewLogEventHandler(object sender, AddNewLogEventArgs e);   
      public event AddNewLogEventHandler AddNewLog;
      public class AddNewLogEventArgs : EventArgs {
        public Log {get; private set;}
        public AddNewLogEventArgs(Log log){
          Log = log;
        }
      }
      protected virtual void OnAddNewLog(AddNewLogEventArgs e){
        AddNewLogEventHandler handler = AddNewLog;
        if(handler != null) handler(this, e);
      }
      public void AddLog(Exception ex) {
         Log newLog = new Log(ex.Message, ex.InnerException);
         singleton._logs.Add(newLog);       
         OnAddNewLog(new AddNewLogEventArgs(newLog));
      }
      public void AddLog(string text) {
         Log newLog = new Log(text);
         singleton._logs.Add(newLog);
         OnAddNewLog(new AddNewLogEventArgs(newLog));
      }
      
      LogOperations.Instance.AddNewLog += (s,e) => {
         var dt = (DataTable) gdcErrorLog.DataSource;
         dt.Rows.Add(e.Log.Time, e.Log.Err, e.Log.Ex.Message);
      };
      
      在主窗体(使用网格)中,可以执行以下操作:

      public delegate void AddNewLogEventHandler(object sender, AddNewLogEventArgs e);   
      public event AddNewLogEventHandler AddNewLog;
      public class AddNewLogEventArgs : EventArgs {
        public Log {get; private set;}
        public AddNewLogEventArgs(Log log){
          Log = log;
        }
      }
      protected virtual void OnAddNewLog(AddNewLogEventArgs e){
        AddNewLogEventHandler handler = AddNewLog;
        if(handler != null) handler(this, e);
      }
      public void AddLog(Exception ex) {
         Log newLog = new Log(ex.Message, ex.InnerException);
         singleton._logs.Add(newLog);       
         OnAddNewLog(new AddNewLogEventArgs(newLog));
      }
      public void AddLog(string text) {
         Log newLog = new Log(text);
         singleton._logs.Add(newLog);
         OnAddNewLog(new AddNewLogEventArgs(newLog));
      }
      
      LogOperations.Instance.AddNewLog += (s,e) => {
         var dt = (DataTable) gdcErrorLog.DataSource;
         dt.Rows.Add(e.Log.Time, e.Log.Err, e.Log.Ex.Message);
      };
      

      注意:您应该删除
      专用frmMain frm在旧类中。

      关于
      GetLogsAsDataTable
      的代码呢?我不认为这很重要,它只是一个foreach,它迭代
      集合日志
      ,并将每个属性写入数据表中的一列。但是
      数据表的
      结构
      很重要。它是否具有所有3列
      异常、消息和时间
      ?“异常”列的类型是什么?不确定它是否是
      系统.Exception
      。编辑为包含GetLogsAsDataTable。仍然不确定它为什么重要,GridControl不关心表是什么。我只是不知道如何从
      LogOperations
      内部与GridControl“对话”。您必须将类
      LogOps
      声明为
      public
      问题是我不确定如何正确地将表单引用传递到此
      LogOperations
      类。。。所以我不能把你的最后两行写进去。如果实例为空,我是否最好只创建一个方法来设置它?这似乎很糟糕。@sab669查看我的更新,您的
      登录操作是作为单例实现的,因此您不能定义任何字段来保存任何外部实例。谢谢,我尝试过实现它,但您的确切示例中出现了一些错误。我做了一些轻微的调整,现在我有两个错误。我将我的帖子编辑到我的整个代码示例中。你能看一下吗?谢谢。@sab669我还在您的问题下留下了一条评论,您的
      登录应该声明为
      公共