最新消息:VPS服务器又从fzhost.net换回Linode了,主题仍用朋友推荐的大前端D8

【已解决】C#中用NLog的RichTextBoxTarget结果始终创建新窗口

C# crifan 1949浏览 0评论

【问题】

折腾:

【未解决】C#中实现Log同时输出内容到文件和文本框(或终端)

过程中,用参考官网的示例代码:

Multiple targets

然后去用NLog的RichTextBoxTarget,代码如下:

        private void initLogger()
        {
            //logger = LogManager.GetCurrentClassLogger();

            // Step 1. Create configuration object 
            LoggingConfiguration logConfig = new LoggingConfiguration();

            // Step 2. Create targets and add them to the configuration 
            RichTextBoxTarget rtbTarget = new RichTextBoxTarget();
            logConfig.AddTarget("richTextBox", rtbTarget);
            //http://nlog.codeplex.com/workitem/2707
            rtbTarget.ControlName = "rtbLog";
            //rtbTarget.FormName = "rtbLog";
            FileTarget fileTarget = new FileTarget();
            logConfig.AddTarget("logFile", fileTarget);

            // Step 3. Set target properties
            rtbTarget.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}";
            fileTarget.FileName = "${basedir}/${date}_log.txt";
            fileTarget.Layout = "${message}";

            // Step 4. Define rules
            LoggingRule rule1 = new LoggingRule("*", LogLevel.Debug, rtbTarget);
            logConfig.LoggingRules.Add(rule1);

            LoggingRule rule2 = new LoggingRule("*", LogLevel.Debug, fileTarget);
            logConfig.LoggingRules.Add(rule2);

            // Step 5. Activate the configuration
            LogManager.Configuration = logConfig;

            // Example usage
            Logger logger = LogManager.GetLogger("Example");
            logger.Trace("trace log message");
            logger.Debug("debug log message");
            logger.Info("info log message");
            logger.Warn("warn log message");
            logger.Error("error log message");
            logger.Fatal("fatal log message");
        }

结果可以显示出RichTextBox,但是是每次都新建一个,而不是我们所希望的,用自己的已有的rtbLog的那个RichTextBox:

indeed create new Nlog window

 

【解决过程】

1.继续参考:

RichTextBox target always opens new form

其说是,需要在NLog的配置文件中找对应的formName的。

但是很明显,此处没有配置文件,而只是代码中去配置的。

2.想到了,是不是由于当前的代码是在winform_Load中加载的,而此处整个窗体还没有完全初始化完毕,所以找不到对应的Winform中的rtxLog的。那就在xxx_Load之后,再去运行此logger的初始化。

改为:

        private void initLogger()
        {
            //logger = LogManager.GetCurrentClassLogger();

            // Step 1. Create configuration object 
            LoggingConfiguration logConfig = new LoggingConfiguration();

            // Step 2. Create targets and add them to the configuration 
            RichTextBoxTarget rtbTarget = new RichTextBoxTarget();
            logConfig.AddTarget("richTextBox", rtbTarget);
            //http://nlog.codeplex.com/workitem/2707
            //rtbTarget.ControlName = "rtbLog";
            rtbTarget.FormName = "rtbLog";
            FileTarget fileTarget = new FileTarget();
            logConfig.AddTarget("logFile", fileTarget);

            // Step 3. Set target properties
            rtbTarget.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}";
            fileTarget.FileName = "${basedir}/${date}_log.txt";
            fileTarget.Layout = "${message}";

            // Step 4. Define rules
            LoggingRule rule1 = new LoggingRule("*", LogLevel.Debug, rtbTarget);
            logConfig.LoggingRules.Add(rule1);

            LoggingRule rule2 = new LoggingRule("*", LogLevel.Debug, fileTarget);
            logConfig.LoggingRules.Add(rule2);

            // Step 5. Activate the configuration
            LogManager.Configuration = logConfig;

            // Example usage
            Logger logger = LogManager.GetLogger("Example");
            logger.Trace("trace log message");
            logger.Debug("debug log message");
            logger.Info("info log message");
            logger.Warn("warn log message");
            logger.Error("error log message");
            logger.Fatal("fatal log message");
        }


        private void btnInitLogger_Click(object sender, EventArgs e)
        {
            initLogger();
        }

        private void frmScrapeAmazonProduct_Load(object sender, EventArgs e)
        {
            //initLogger();

            //debug
            ////init
            //initMainCategoryToBestSellerCategoryMapping();

            //outputExcelFullFilename = Path.Combine(Environment.CurrentDirectory, outputExcelFilename);

            //initSearchCategory();
        }

结果问题依旧。

3.再去参考之前就看到的:

NLog control to an existing RichTextBox Windows Form

才有点明白:

FormName:指的是Winform,即当前的frmScrapeAmazonProduct

ControlName:指的是RichTextBox ,即此处的rtbLog

所以,再去试试:

private void initLogger()
{
    //logger = LogManager.GetCurrentClassLogger();

    // Step 1. Create configuration object 
    LoggingConfiguration logConfig = new LoggingConfiguration();

    // Step 2. Create targets and add them to the configuration 
    RichTextBoxTarget rtbTarget = new RichTextBoxTarget();
    logConfig.AddTarget("richTextBox", rtbTarget);
    //http://nlog.codeplex.com/workitem/2707
    rtbTarget.ControlName = "rtbLog";
    rtbTarget.FormName = "frmScrapeAmazonProduct";
    FileTarget fileTarget = new FileTarget();
    logConfig.AddTarget("logFile", fileTarget);

    // Step 3. Set target properties
    rtbTarget.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}";
    fileTarget.FileName = "${basedir}/${date}_log.txt";
    fileTarget.Layout = "${message}";

    // Step 4. Define rules
    LoggingRule rule1 = new LoggingRule("*", LogLevel.Debug, rtbTarget);
    logConfig.LoggingRules.Add(rule1);

    LoggingRule rule2 = new LoggingRule("*", LogLevel.Debug, fileTarget);
    logConfig.LoggingRules.Add(rule2);

    // Step 5. Activate the configuration
    LogManager.Configuration = logConfig;

    // Example usage
    Logger logger = LogManager.GetLogger("Example");
    logger.Trace("trace log message");
    logger.Debug("debug log message");
    logger.Info("info log message");
    logger.Warn("warn log message");
    logger.Error("error log message");
    logger.Fatal("fatal log message");
}

private void frmScrapeAmazonProduct_Load(object sender, EventArgs e)
{
    initLogger(); // init logger in winform1_Load here, also work

    //debug
    ////init
    //initMainCategoryToBestSellerCategoryMapping();

    //outputExcelFullFilename = Path.Combine(Environment.CurrentDirectory, outputExcelFilename);

    //initSearchCategory();
}

果然可以了:

会在当前的Winform类frmScrapeAmazonProduct下面的名为rtbLog的RichTextBox控件(control)中,输出上述log信息:

ouput log info to richtextbox within winform

 

【总结】

想要让RichTextBoxTarget,输出内容到自己的RichTextBox控件中

(而不要每次都是重新创建一个另外的,新的RichTextBox控件)

那么要确保:

RichTextBoxTarget的初始化时,对应的FormName和ControlName都要初始化正确,名字确保要正确。

然后正常的,在窗体的load中,即形如winform1_Load的函数中,去初始化即可。

(此时,由于是winform的load,所以之前的winform的构造函数中,已经调用了InitializeComponent,已经初始化好了自己的那个RichTextBox了,所以此处是可以找到自己的那个RichTextBox)

 

核心相关代码为:

private void initLogger()
{
    ......
    RichTextBoxTarget rtbTarget = new RichTextBoxTarget();
    logConfig.AddTarget("richTextBox", rtbTarget);
    rtbTarget.FormName = "frmScrapeAmazonProduct"; // your winform class name
    rtbTarget.ControlName = "rtbLog"; // your RichTextBox control/variable name
    ......
}

private void winform1_Load(object sender, EventArgs e)
{
    initLogger();
}

就可以了。

转载请注明:在路上 » 【已解决】C#中用NLog的RichTextBoxTarget结果始终创建新窗口

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

网友最新评论 (1)

  1. 看了你的2篇有关NLog的文章,真是获益非浅啊 你都把解决步骤写出来了,比我细心太多了 赞!!!
    磊哥2年前 (2016-07-19)回复
57 queries in 0.231 seconds, using 12.14MB memory