无法将 ItemsControl 绑定到 ObservableCollection

Cannot bind ItemsControl to ObserveableCollection

如标题所述,我在将 ObservableCollection 绑定到 ItemsControl 时遇到问题。

MainWindow.xaml:

xmlns:ext="clr-namespace:DeConfigurator.Classes"

...

<ItemsControl ItemsSource="{Binding Source=ext:InAppSink.Logs}" Name="LogList">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
       <Expander Header="{Binding Level}">
         <TextBlock TextWrapping="Wrap">
            <TextBlock.Text>
               <Binding Path="FormattedEntry" />
            </TextBlock.Text>
         </TextBlock>
       </Expander>
     </DataTemplate>
   </ItemsControl.ItemTemplate>                                    

InAppSink:

namespace DeConfigurator.Classes
{
    public class InAppSink : ILogEventSink
    {
        static readonly int MAX_ITEMS = 200;
        static readonly int TO_REMOVE = 50;
        
        public ObservableCollection<LogItem> Logs { get; set; } = new ObservableCollection<LogItem>();

        public void Emit(LogEvent logEvent)
        {
            if (logEvent == null){throw new ArgumentNullException(nameof(logEvent)); }            

            if(Logs.Count > MAX_ITEMS)
            {
                for(int i = 0; i < TO_REMOVE; ++i)
                {
                    Logs.RemoveAt(i);
                }
            }

            Logs.Add(new LogItem(logEvent));            
        }
    }

    public class LogItem
    {
        readonly ITextFormatter _textFormatter =
            new MessageTemplateTextFormatter(
                "{Timestamp:yyyy-MM-dd HH:mm:ss zzz} [{Level}] [{Method}] {Message:lj}{NewLine}{Properties:j}{NewLine}{Exception}"
        );


        public string FormattedEntry { get; set; }
        public string Level { get; set; }
        public DateTime LogDate { get; set; }

        public LogItem(LogEvent logEvent)
        {
            var renderSpace = new StringWriter();
            _textFormatter.Format(logEvent, renderSpace);
            FormattedEntry = renderSpace.ToString();

            Level = logEvent.Level.ToString();
            LogDate = logEvent.Timestamp.DateTime;

        }
    }
}

我想要的结果是让每个日志条目显示为折叠的扩展器,级别和日期作为 header,格式化的日志条目作为放置时的文本内容。我得到的是文本“ext:InAppSink.Logs”中的每个字符用于创建扩展器 objects。为什么这个绑定不起作用?

为了绑定到对象的 属性,您必须将绑定的 Path 设置为源 属性 的名称,而源对象通常是通过 Binding 的目标对象的 DataContext 传递。

有关详细信息,请参阅 Microsoft 文档中的 Data binding overview


所以替换

ItemsSource="{Binding Source=ext:InAppSink.Logs}"

ItemsSource="{Binding Path=Logs}"

并将 InAppSink class 的实例分配给视图的 DataContext,例如在 MainWindow 构造函数中:

private readonly InAppSink sink = new InAppSink();

public MainWindow()
{
    InitializeComponent();
    DataContext = sink;
}

Logs 属性 也应该是只读的,比如

public ObservableCollection<LogItem> Logs { get; } = new ObservableCollection<LogItem>();

或发出更改通知。