来自TextFile的Lifeupdate DataGrid具有良好的性能
实际状态:
我有一个带有4列的DataGrid
(Icon | DateTime | LogLevel | Message)
我用它作为查看器来呈现LogFile
条目。 打开Window
,UI滞后,很多条目逐个添加到DataGrid
。
注意:我已经在使用多个线程。 我的UI-Thread没有冻结。 它只是采取长期填充整个DataGrid
。
我想要的是:
在向用户展示之前,我更喜欢“预渲染”整个窗口之类的东西。
当我打开Window
一次 – 每次我再次打开它时,它就不再有问题了。(不能渲染新的……?)
我试过的:
- 将
Visibility
设置为Hidden
并等待(Thread.Sleep()
)10秒然后设置Visibility = Visibility.Visible
; - 在ViewModel-Constructor中将所有数据添加到我的
DataGrid
中
但这一切并没有真正解决它。 我甚至不确定它是C#代码还是只是Bindings ……
这可能是一个愚蠢的问题,但有没有办法在显示之前“预渲染” DataGrid
及其Content
?
编辑:
我也使用一些DataTriggers
来设置RowColor,但这可能不是问题。
这是我使用的一些代码:
入门级:
public class LogEntry { public string LogLevel { get; set; } public string LogLevelIcon { get { switch(LogLevel) { case "[D]": //IF DEBUG ENTRY: return "pack://application:,,,/Resources/Bug.png"; case "[F]": //IF FATAL ENTRY return "pack://application:,,,/Resources/System-error-alt.png"; case "[E]": //IF ERROR ENTRY return "pack://application:,,,/Resources/Error_32_WhiteBackground.png"; case "[I]": //IF INFO ENTRY return "pack://application:,,,/Resources/Info_32.png"; case "[W]": //IF WARNING ENTRY return "pack://application:,,,/Resources/Warning_32_WhiteBackground.png"; case "[DB]": //IF DB ENTRY return "pack://application:,,,/Resources/Database.png"; default: return string.Empty; } } } public string Message { get; set; } public DateTime DateTime { get; set; } public override string ToString() { return $"{LogLevel};{DateTime.ToString("dd.MM.yyyy HH:mm:ss")};{Message}"; } }
从我的LogFile获取数据:
public void ExtractDataFromLogFile(string logFilePath) { new Thread(() => { List linesInFile = new List(); using (FileStream stream = File.Open(logFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (StreamReader reader = new StreamReader(stream)) { while (true) { while (!reader.EndOfStream) { ProcessFileContent(reader.ReadLine()); } while (reader.EndOfStream) { Thread.Sleep(50); } } } } }).Start(); }
添加到
ObservableCollection() _logEntries;
:
private void ProcessFileContent(string line) { Match match = _regex.Match(line); if (match.Success) { LogEntry entry = new LogEntry() { LogLevel = match.Groups[1].ToString(), DateTime = DateTime.Parse(match.Groups[2].ToString(), new CultureInfo("de-DE")), Message = match.Groups[3].ToString() }; _logEntries.Add(entry); } }
最后是DataGrid的XAML(样式省略了!):
请注意,“ItemsView”是ICollectionView
我在这里填写:
private void InitializeCollection() { ItemsView = CollectionViewSource.GetDefaultView(_logEntries); BindingOperations.EnableCollectionSynchronization(_logEntries, _lock); }
从文件中读取,您应该更改为:
XAML:
C#代码:
Dispatcher DP = Dispatcher.CurrentDispatcher; public void ExtractDataFromLogFile(string logFilePath) { new Thread(() => { var lines = File.ReadAllLines(logFilePath); foreach (var line in lines) ProcessFileContent(line); DP.Invoke(() => DataGrid.DataContext = _logEntries); }).Start(); } private void ProcessFileContent(string line) { Match match = _regex.Match(line); if (match.Success) { LogEntry entry = new LogEntry() { LogLevel = match.Groups[1].ToString(), DateTime = DateTime.Parse(match.Groups[2].ToString(), new CultureInfo("de-DE")), Message = match.Groups[3].ToString() }; _logEntries.Add(entry); } }
如果您对_logEntries
有任何绑定,请_logEntries
将其删除。
请将其命名如下:
ExtractDataFromLogFile("yourLogFile");
这会将您的数据加载到_logEntries
,完成后,它会自动绑定到DataGrid
。