You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#跨类调用日志导出方法遇DependencyProperty重复注册错误求助

问题解决方案

一、先修复DependencyProperty重复注册错误

WPF的依赖属性必须定义为静态只读字段,因为依赖属性是全局注册的,每个类型只能注册一次。你的代码把IsUserConnectedProperty定义为实例字段,每次实例化MainWindow都会执行DependencyProperty.Register,导致重复注册报错。

修改依赖属性定义:

// 改为静态只读字段
public static readonly DependencyProperty IsUserConnectedProperty =
    DependencyProperty.Register("IsUserConnected", typeof(bool), typeof(MainWindow), new PropertyMetadata(false));

// 对应的CLR属性(可选但推荐)
public bool IsUserConnected
{
    get => (bool)GetValue(IsUserConnectedProperty);
    set => SetValue(IsUserConnectedProperty, value);
}

二、重构日志导出逻辑,解耦UI依赖

当前exportLogs方法依赖MainWindow的UI控件LogGrid,导致必须实例化窗口才能调用,违反了业务逻辑与UI分离的原则,也会带来窗口实例化的额外问题。正确做法是把日志数据从UI控件中抽离,放到独立的日志管理类中。

1. 创建独立的日志管理类

using System;
using System.IO;
using System.Collections.ObjectModel;

public static class LogManager
{
    // 用ObservableCollection可直接绑定到UI,自动更新显示
    private static readonly ObservableCollection<string> _logEntries = 
        new ObservableCollection<string>();

    // 对外暴露日志集合,供UI绑定
    public static ObservableCollection<string> LogEntries => _logEntries;

    // 添加日志条目
    public static void AddLog(string logText)
    {
        _logEntries.Add(logText);
    }

    // 导出日志到文件
    public static void ExportLogs()
    {
        // 用程序运行目录替代硬编码路径,适配不同环境
        string logsFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "LogsFolder");
        if (!Directory.Exists(logsFolder))
        {
            Directory.CreateDirectory(logsFolder);
        }

        // 用精确时间戳(含年月日),避免短时间内生成同名文件
        string timestamp = DateTime.Now.ToString("yyyyMMddHHmmss");
        string logFileName = Path.Combine(logsFolder, $"Logs_{timestamp}.txt");
        string errorLogFileName = Path.Combine(logsFolder, $"ErrorLog_{timestamp}.txt");

        using (StreamWriter logWriter = new StreamWriter(logFileName))
        using (StreamWriter errorLogWriter = new StreamWriter(errorLogFileName))
        {
            foreach (var entry in _logEntries)
            {
                logWriter.WriteLine(entry);

                // 修正原代码错误:写入日志内容而非文件名
                if (IsErrorLog(entry))
                {
                    errorLogWriter.WriteLine(entry);
                }
            }
        }
    }

    // 判断是否为错误/警告日志
    private static bool IsErrorLog(string logText)
    {
        return logText.Contains(LogType.Error.ToString()) || logText.Contains(LogType.Warning.ToString());
    }
}

2. 修改MainWindow,绑定日志集合到UI

在MainWindow的XAML中,将LogGrid的ItemsSource绑定到日志管理类的集合:

<!-- 根据你的实际Grid结构调整 -->
<Grid x:Name="LogGrid" ItemsSource="{x:Static local:LogManager.LogEntries}">
    <!-- 列定义等UI结构 -->
</Grid>

后续在MainWindow中添加日志,直接调用LogManager.AddLog("日志内容");即可,UI会自动同步更新。

3. 修改SDKService中的调用

删除实例化MainWindow的代码,直接调用日志管理类的静态方法:

public void DeleteCredentials(int nbOfCredentialsToDelete, bool deleteAll, bool deleteMatchingCardholders)
{
    if (ListCredentials.Count == 0)
    {
        LogManager.ExportLogs();
        LogManager.AddLog("No credentials to delete");
        return;
    }
    if (ListCredentials.Count < nbOfCredentialsToDelete)
    {
        LogManager.ExportLogs();
        LogManager.AddLog($"Only {ListCredentials.Count} credential(s) in the system - Impossible to delete {nbOfCredentialsToDelete}");
        return;
    }
    {
        LogManager.ExportLogs();
        LogManager.AddLog("Starting delete");
    }

    // 后续业务逻辑...
}

三、额外修正原代码错误

原exportLogs方法中errorLogWriter.WriteLine(errorLogFileName);是错误的,应该写入日志条目内容而非错误日志文件名,重构代码已修正该问题。

内容的提问来源于stack exchange,提问作者PinkGoat_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 09:34:56