所以我有WPF
个应用程序,我想添加Logger form
。
所以我创建了另一个form
:
public partial class LoggerForm : MetroWindow
{
public LoggerForm()
{
InitializeComponent();
DataContext = LogHelper.LogEntries;
lvLogger.ItemsSource = LogHelper.LogEntries;
}
public void AddRandomEntry(LogEntry logEntry)
{
Dispatcher.BeginInvoke((Action)(() => LogHelper.LogEntries.Add(logEntry)));
}
}
XAML ListView
:
<ListView Name="lvLogger"
Background="#181818"
Margin="0,0,0,0">
<ListView.View>
<GridView>
<GridViewColumn Width="Auto" Header="Time" DisplayMemberBinding="{Binding DateTime}"/>
<GridViewColumn Width="Auto" Header="Index" DisplayMemberBinding="{Binding Index}"/>
<GridViewColumn Width="Auto" Header="Level" DisplayMemberBinding="{Binding Level}"/>
<GridViewColumn Width="Auto" Header="Source" DisplayMemberBinding="{Binding Source}"/>
<GridViewColumn Width="Auto" Header="Message" DisplayMemberBinding="{Binding Message}"/>
</GridView>
</ListView.View>
</ListView>
记录object
:
public class LogEntry
{
public string DateTime { get; set; }
public int Index { get; set; }
public string Source{ get; set; }
public Level Level { get; set; }
public string Message { get; set; }
}
列表:
public class LogHelper
{
public static ObservableCollection<LogEntry> LogEntries { get; set; }
}
这就是我将日志添加到我的列表中的方式:
打开我的记录器form
:
Thread newWindowThread = new Thread(new ThreadStart(() =>
{
// Create and show the Window
loggerForm = new LoggerForm();
loggerForm.Show();
// Start the Dispatcher Processing
Dispatcher.Run();
}));
// Set the apartment state.
newWindowThread.SetApartmentState(ApartmentState.STA);
newWindowThread.IsBackground = true;
newWindowThread.Start();
从我的主form
我创建LogEntry
对象并添加它:
private void AddLog(Level level, string message)
{
if (loggerForm != null)
{
LogEntry logEntry = new LogEntry()
{
DateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff"),
Index = LogHelper.LogEntries.Count,
Level = level,
Source = "bla bla",
Message = message
};
loggerForm.AddRandomEntry(logEntry);
}
}
所以这个工作正常,直到我关闭Logger
表单并再次打开它。此时,如果我添加了另一个LogEntry
,我会在error
方法中使用AddRandomEntry
:
System.NotSupportedException:&#39;这种类型的CollectionView没有 支持从不同的线程更改其SourceCollection Dispatcher线程。&#39;
答案 0 :(得分:-1)
Your problem is due to your separate threads. My advice would be to not start your new thread at all.
Thread newWindowThread = new Thread(new ThreadStart(() =>
and
newWindowThread.SetApartmentState(ApartmentState.STA);
newWindowThread.IsBackground = true;
newWindowThread.Start();
All bad. Don't do it. It is almost never a good idea to have more than one thread for UI.