Текущее состояние:
У меня DataGrid
с 4 столбцами (значок | DateTime | LogLevel | Сообщение)
Я использую его как средство просмотра, чтобы представить записи о LogFile
. При открытии Window
пользовательский интерфейс задерживается, и множество записей добавляются одна за другой к DataGrid
.
Примечание. Я уже использую несколько потоков. Моя UI-Thread не зависает. Просто нужно слишком много времени, чтобы заполнить весь DataGrid
.
Чего я хочу:
Я бы предпочел что-то вроде «предварительного рендеринга» всего окна, прежде чем показывать его пользователю.
Когда я открывал Window
один раз - каждый раз, когда я открываю его снова, это больше не проблема. (Не рендеринг нового ....?)
Что я пробовал:
- Установите
Visibility
наHidden
и подождите (Thread.Sleep()
) 10 секунд, затем установитеVisibility = Visibility.Visible
; - Добавление всех данных в мой
DataGrid
в ViewModel-Constructor
но все это на самом деле не исправило. Я даже не уверен, это код C # или просто привязки ...
Это может быть глупый вопрос, но есть ли способ «предварительно отрендерить» 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}";
}
}
Получение данных из моего файла журнала:
public void ExtractDataFromLogFile(string logFilePath)
{
new Thread(() => {
List<string> linesInFile = new List<string>();
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<LogEntry>() _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);
}
}
Наконец, XAML DataGrid (стили исключены!):
<DataGrid Grid.Row="1"
x:Name="DataGrid"
Grid.ColumnSpan="2"
Margin="5"
IsReadOnly="True"
AutoGenerateColumns="False"
CanUserReorderColumns="False"
ItemsSource="{Binding Path=ItemsView, UpdateSourceTrigger=PropertyChanged}">
<DataGrid.Columns>
<DataGridTemplateColumn Width="Auto">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding Path=LogLevelIcon, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Width="16"
Height="16"></Image>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Width="Auto" Header="Datum"
Binding="{Binding Path=DateTime, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Width="*" Header="Meldung"
Binding="{Binding Path=Message, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataGrid.Columns>
</DataGrid>
Обратите внимание, что ItemsView имеет тип ICollectionView
Заливаю сюда:
private void InitializeCollection()
{
ItemsView = CollectionViewSource.GetDefaultView(_logEntries);
BindingOperations.EnableCollectionSynchronization(_logEntries, _lock);
}
ObservableCollection
(если вы его используете), и определение XAML вашегоDataGrid
. - person toadflakz   schedule 24.02.2016ObservableCollection
и активируя изменение, поэтому просмотр может обновлять контент. Я ожидаю, что виртуализация будет игнорировать обновления невидимых вещей, поэтому в целом это должно быть быстрее, чем полностью синхронная загрузка. - person Sinatr   schedule 24.02.2016ColumnWidth
установлен на Авто для всех, кроме сообщения. Этот заполняет ... - person Felix D.   schedule 24.02.2016