在从TraceListener继承的自定义跟踪侦听器中实现时,Observable Collection将变为null

本文关键字:Collection Observable null 实现 继承 TraceListener 自定义 跟踪 侦听器 在从 | 更新日期: 2023-09-27 18:21:31

我创建了一个从TraceListner类继承的自定义跟踪侦听器。实际上,这个想法是在应用程序中使用Trace.Write方法,该方法应该更新自定义跟踪侦听器类中的Observable集合,该类可以绑定到框架元素。

这是我的自定义跟踪侦听器:

public class CustomTraceListener : TraceListener, INotifyPropertyChanged
{
    private ObservableCollection<TraceMessageInfo> _traceLogs;
    public ObservableCollection<TraceMessageInfo> TraceLogs
    {
        get
        {
            return _traceLogs;
        }
        set
        {
            _traceLogs = value;
            OnPropertyChanged("TraceLogs");
        }
    }
    public CustomTraceListener()
    {
        if (TraceLogs == null)
        {
            TraceLogs = new ObservableCollection<TraceMessageInfo>();
            TraceLogs.Add(new TraceMessageInfo("Message", Enums.TraceCategory.Information.ToString()));
        }
    }
    public override void Write(object traceMessageInfo)
    {
        TraceLogs.Add(new TraceMessageInfo("New message", Enums.TraceCategory.Information.ToString()));
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }   
}

下面是我用来将可观察集合绑定到ListBox(WPF)的xaml。

<StackPanel Grid.Row="1" Name="TraceLogStackPanel">
                    <ListBox Name="lbTraceViewer" ItemsSource="{Binding TraceLogs, Mode=TwoWay}">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Width="700" Background="{Binding Category,Converter={StaticResource TraceCategoryToColorConverter}, Mode=TwoWay}">
                                    <Label Content="{Binding Message, Mode=TwoWay}" />
                                </StackPanel>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                </StackPanel>

在构造函数中,我将堆栈面板的数据上下文设置为这个新的跟踪侦听器。

this.TraceLogStackPanel.DataContext = new CustomTraceListener();

最后,在点击执行按钮时,我将为我的自定义跟踪侦听器的写入方法设置一条伪消息。

private void Button_Click(object sender, RoutedEventArgs e)
    {            
        Trace.Write(new TraceMessageInfo("Message",Enums.TraceCategory.Error.ToString())); 
    }

在配置文件中,我设置了自定义跟踪侦听器,并删除了默认的侦听器。

我的问题是,当我单击execute时,集合中没有任何更改。有时当我尝试调试时,它会将集合显示为null,有时它会显示集合已更改,但没有通知UI。列表框只显示我在自定义侦听器的构造函数中设置的一条消息。

任何帮助都将不胜感激。

在从TraceListener继承的自定义跟踪侦听器中实现时,Observable Collection将变为null

好吧,因为您正在创建CustomTraceListener的实例,所以您的视图绑定到与.NET跟踪系统不同的实例(它将创建自己的实例)。我会将集合更改为静态实例,这样您将看到所有消息:

private static readonly ObservableCollection<TraceMessageInfo> _traceLogs;
public ObservableCollection<TraceMessageInfo> TraceLogs
{
    get
    {
        return _traceLogs;
    }
}
static CustomTraceListener()
{
    _traceLogs = new ObservableCollection<TraceMessageInfo>();
    _traceLogs.Add(new TraceMessageInfo("Message", Enums.TraceCategory.Information.ToString()));
}