WPF:这种类型的CollectionView不支持更改错误

时间:2018-03-25 17:59:03

标签: wpf multithreading forms log4net

所以我有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;

1 个答案:

答案 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.