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_
相关产品推荐
相关产品推荐

