Okay, ich habe eine Lade-Animation, die ausgeführt wird, während eine große DataTable ausgefüllt wird, um den Benutzer wissen zu lassen, dass das Programm nicht eingefroren ist. Ich habe die Animation gut funktioniert, aber es friert ein, während die DataTable auch aktualisiert wird. Gibt es eine Möglichkeit, mehrere UI-Threads zu verwenden, sodass die Animation weiterhin ausgeführt wird, während die DataTable Informationen lädt?WPF lädt Animation in einem separaten UI-Thread? (C#)
BEARBEITEN: Der aktuelle Code ist unten.
private void CreateFileTable()
{
file_data = new DataSet();
data_table = new DataTable();
file_data.Tables.Add(data_table);
DataColumn tempCol = new DataColumn("File Name", typeof(string));
data_table.Columns.Add(tempCol);
tempCol = new DataColumn("Ext", typeof(string));
data_table.Columns.Add(tempCol);
tempCol = new DataColumn("Size", typeof(string));
data_table.Columns.Add(tempCol);
tempCol = new DataColumn("Created", typeof(Label));
data_table.Columns.Add(tempCol);
tempCol = new DataColumn("Modified", typeof(Label));
data_table.Columns.Add(tempCol);
tempCol = new DataColumn("Accessed", typeof(Label));
data_table.Columns.Add(tempCol);
tempCol = new DataColumn("Location", typeof(string));
data_table.Columns.Add(tempCol);
File_List.ItemsSource = file_data.Tables[0].DefaultView;
}
private void PopulateDirectories(string[] directories)
{
for (int i = 0; i < directories.Length; i++)
{
DirectoryInfo tempDirInfo = new DirectoryInfo(directories[i]);
bool isSystem = ((tempDirInfo.Attributes & FileAttributes.System) == FileAttributes.System);
if (!isSystem)
{
DataRow tempRow = data_table.NewRow();
tempRow["File Name"] = tempDirInfo.Name;
tempRow["Ext"] = "";
tempRow["Size"] = "";
tempLabel = new Label();
tempLabel.Padding = new Thickness(2, 0, 2, 0);
tempLabel.Content = tempDirInfo.CreationTime.ToLongDateString() + ", " + tempDirInfo.CreationTime.ToLongTimeString();
tempRow["Created"] = tempLabel;
tempLabel = new Label();
tempLabel.Padding = new Thickness(2, 0, 2, 0);
tempLabel.Content = tempDirInfo.LastWriteTime.ToLongDateString() + ", " + tempDirInfo.LastWriteTime.ToLongTimeString();
tempRow["Modified"] = tempLabel;
tempLabel = new Label();
tempLabel.Padding = new Thickness(2, 0, 2, 0);
tempLabel.Content = tempDirInfo.LastAccessTime.ToLongDateString() + ", " + tempDirInfo.LastAccessTime.ToLongTimeString();
tempRow["Accessed"] = tempLabel;
tempRow["Location"] = tempDirInfo.FullName;
data_table.Rows.Add(tempRow);
}
}
}
private void PopulateFiles(string[] files)
{
for (int i = 0; i < files.Length; i++)
{
FileInfo tempFileInfo = new FileInfo(files[i]);
bool isSystem = ((File.GetAttributes(files[i]) & FileAttributes.System) == FileAttributes.System);
if (!isSystem)
{
DataRow tempRow = data_table.NewRow();
tempRow["File Name"] = tempFileInfo.Name;
tempRow["Ext"] = tempFileInfo.Extension;
int fileSize = (int)tempFileInfo.Length;
if (fileSize > 1048576)
{
tempRow["Size"] = "" + fileSize/1048576 + " MB";
}
else if (fileSize > 1024)
{
tempRow["Size"] = "" + fileSize/1024 + " KB";
}
else
{
tempRow["Size"] = "" + fileSize + " B";
}
tempLabel = new Label();
tempLabel.Padding = new Thickness(2, 0, 2, 0);
tempLabel.Content = tempFileInfo.CreationTime.ToLongDateString() + ", " + tempFileInfo.CreationTime.ToLongTimeString();
tempRow["Created"] = tempLabel;
tempLabel = new Label();
tempLabel.Padding = new Thickness(2, 0, 2, 0);
tempLabel.Content = tempFileInfo.LastWriteTime.ToLongDateString() + ", " + tempFileInfo.LastWriteTime.ToLongTimeString();
tempRow["Modified"] = tempLabel;
tempLabel = new Label();
tempLabel.Padding = new Thickness(2, 0, 2, 0);
tempLabel.Content = tempFileInfo.LastAccessTime.ToLongDateString() + ", " + tempFileInfo.LastAccessTime.ToLongTimeString();
tempRow["Accessed"] = tempLabel;
tempRow["Location"] = tempFileInfo.DirectoryName;
data_table.Rows.Add(tempRow);
}
}
}
private string GetSelectedPath(TreeViewItem selectedNode)
{
return selectedNode.Tag as string;
}
private void PopulateFileList()
{
PopulateDirectories(Directory.GetDirectories(GetSelectedPath((TreeViewItem)Dir_Tree.SelectedItem)));
PopulateFiles(Directory.GetFiles(GetSelectedPath((TreeViewItem)Dir_Tree.SelectedItem)));
}
private void UpdateFileList()
{
LoadingWheel.Visibility = System.Windows.Visibility.Visible;
CreateFileTable();
PopulateFileList();
TxtFoundCount.Text = "Files/Folders Found: " + File_List.Items.Count;
LoadingWheel.Visibility = System.Windows.Visibility.Hidden;
}
Ich habe versucht, die Background verwenden und den UpdateFileList() -Methode im Innern nennen, aber ich habe kein Glück.
EDIT: Unten ist mein Code für den BackgroundWorker.
private BackgroundWorker bgWorker1;
private void InitializeBackgroundWorker()
{
bgWorker1 = new BackgroundWorker();
bgWorker1.DoWork += new DoWorkEventHandler(bgWorker1_DoWork);
bgWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker1_RunWorkerCompleted);
}
private void bgWorker1_DoWork(object sender, DoWorkEventArgs e)
{
if (Dispatcher.CheckAccess())
{
PopulateFileList();
}
else
{
Dispatcher.Invoke(new Action(() => PopulateFileList()));
}
}
private void bgWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
TxtFoundCount.Text = "Files/Folders Found: " + File_List.Items.Count;
LoadingWheel.Visibility = System.Windows.Visibility.Hidden;
}
private void UpdateFileList()
{
LoadingWheel.Visibility = System.Windows.Visibility.Visible;
CreateFileTable();
bgWorker1.RunWorkerAsync();
}
Ich habe ein Selection Ereignis auf einem TreeView, die InitializeBackgroundWorker() und UpdateFileList() aufruft. Die Liste lädt immer noch, und ich bekomme keine Fehler, aber die Lade-Animation wird nie sichtbar.
Jede Hilfe würde sehr geschätzt werden.
Danke.
Wo sind Ihre Mitarbeiter im Hintergrund? –
Ich nahm den BackgroundWorker-Code wieder heraus, weil es mehr Code war und nichts half. Ich kann es wieder einfügen, aber ich bin mir ziemlich sicher, dass ich es falsch gemacht habe. –
In diesem Fall würden Sie wahrscheinlich die RunWorkerAsync-Funktion des Hintergrundarbeiters von UpdateFileList aufrufen, nachdem Sie LoadingWheel aktiviert haben. Verschieben Sie die beiden Funktionsaufrufe an bgWorker_DoWork, die Aktualisierung an den TextBlock an bgWorker_ProgressChanged, und deaktivieren Sie LoadingWheel in bgWorker_RunWorkerCompleted. Siehe aktualisierte Antwort. –