为什么我的ObservableCollection没有被注意到
本文关键字:注意到 我的 ObservableCollection 为什么 | 更新日期: 2023-09-27 18:28:50
我在用户控件中有以下元素,作为默认Grid
:的唯一子元素
<ListView ItemsSource="{Binding LogCollection}" Name="LogView">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn DisplayMemberBinding="{Binding Level}" Header="Level"/>
<GridViewColumn DisplayMemberBinding="{Binding FormattedMessage}" Width="500" Header="Message"/>
<GridViewColumn DisplayMemberBinding="{Binding Exception}" Header="Exception"/>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
在后面的代码中,我将处理来自自定义NLog Target
的以下事件。我之所以这么处理它,是因为给了我一个例子,一个完整的WPF noob,但它似乎还可以
private void EventReceived(LogEventInfo message)
{
Dispatcher.Invoke(() =>
{
if (LogCollection.Count >= 50)
{
LogCollection.RemoveAt(LogCollection.Count - 1);
}
LogCollection.Add(message);
});
}
事件触发良好,当我逐步执行代码时,Add
调用已到达。当我在执行时将鼠标悬停在XAML视图中的LogCollection
上时,在Add call, yet my
ListView`保持幸福的状态后,我会看到一个"Count=1",它不知道它应该向我显示一个日志事件。
好的,好的,我的用户控制的节略代码是:
public partial class LoggingControl : UserControl
{
public ObservableCollection<LogEventInfo> LogCollection { get; set; }
public LoggingControl()
{
LogCollection = new ObservableCollection<LogEventInfo>();
InitializeComponent();
foreach (Target target in LogManager.Configuration.AllTargets)
{
var memoryEventTarget = target as MemoryEventTarget;
if (memoryEventTarget != null)
{
memoryEventTarget.EventReceived += EventReceived;
}
}
}
private void EventReceived(LogEventInfo message)
{
Dispatcher.BeginInvoke(new Action(() =>
{
LogCollection.Add(message);
}));
}
}
如注释中所述,ListView.ItemsSource
绑定的绑定上下文似乎是错误的。DataContext
。在您的情况下,手动设置DataContext
可以解决问题
this.DataContext = this;
但这需要在创建LogCollection
之后完成,因为属性本身不会引发INotifyPropertyChanged.PropertyChanged
事件。
要回答为什么DataContext
在默认情况下不设置为self,是因为DataContext
在整个视觉树中都是继承的。因此,UserControl
和任何其他FrameworkElement
一样,默认情况下将从放置它的元素继承它的DataContext
。
另一件值得注意的事情是,只能有一个DataContext
值。它将从可视化树中继承或在UserControl
中手动设置。您可以使用继承的上下文,并且仍然可以通过使用RelativeSource
或ElementName
绑定来绑定到UserControl
属性。
<UserControl ... x:Name="myUserControl">
<!-- --->
<ListView ItemsSource="{Binding LogCollection, ElementName=myUserControl}" Name="LogView">
您确定实际添加项目的LogCollection就是您将网格绑定到的那个吗?我已经创建了一个示例应用程序,该应用程序包含您的代码,但工作正常?也许你需要发布更多的代码。
这是我的应用程序示例。
也许您的ItemsSource绑定现在正在工作。您在控制台中看到任何绑定错误吗?类似于"BindingExpression路径错误:在'object'上找不到'LogCollection'属性"