简体   繁体   English

为什么我的ObservableCollection无法观察?

[英]Why is my ObservableCollection going unobserved?

I have the following element in a user control, as the sole child of the default Grid : 我在用户控件中具有以下元素,作为默认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>

In the code behind, I am handling the following event from a custom NLog Target . 在后面的代码中,我正在处理来自自定义NLog Target的以下事件。 I am only handling it so because of an example given to me, a total WPF noob, but it seems OK. 我只是处理它,因为给出了一个示例,一个完整的WPF新手,但这似乎还可以。

private void EventReceived(LogEventInfo message)
{
    Dispatcher.Invoke(() =>
        {
            if (LogCollection.Count >= 50)
            {
                LogCollection.RemoveAt(LogCollection.Count - 1);
            }
            LogCollection.Add(message);
        });
}

The event fires fine, and the Add call is reach when I step through the code. 事件正常运行,当我单步执行代码时,可以到达Add调用。 When I mouse-over LogCollection in the XAML view at execution time, I see a "Count = 1" after the Add call, yet my ListView` remains blissfully unaware it is supposed to be showing me a log event. 当我在执行时将鼠标悬停在XAML视图中的LogCollection上时,在Add call, yet my之后看到“ Count = 1” call, yet my ListView`仍然非常高兴地没有意识到它应该向我显示一个日志事件。

OK, OK, the abridged code behind for my user control is: 好的,好的,我的用户控件后面的简化代码是:

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);
                    }));
    }
}

As mentioned in comments it seems like binding context for ListView.ItemsSource binding is wrong. 如评论中所述,似乎ListView.ItemsSource绑定的绑定上下文是错误的。 DataContext . DataContext In your case setting DataContext manually could solve the problem 在您的情况下,手动设置DataContext可以解决问题

this.DataContext = this; 

But this needs to be done after LogCollection is created as the property itself does not raise INotifyPropertyChanged.PropertyChanged event. 但这需要在创建LogCollection之后完成,因为属性本​​身不会引发INotifyPropertyChanged.PropertyChanged事件。

And to answer why DataContext is not set to self by default is because DataContext is inherited throughout visual tree. 回答为什么默认不将DataContext设置为self的原因是因为DataContext是在整个可视树中继承的。 So UserControl , as any other FrameworkElement , will by default inherit its DataContext from the element where it was placed. 因此, UserControl与其他任何FrameworkElement ,默认情况下将从其放置的元素继承其DataContext

Another thing worth noting is that there can be only one DataContext value. 另一点值得注意的是,只能有一个DataContext值。 It will be either inherited from visual tree or set manually in your UserControl . 它可以从可视树继承,也可以在UserControl手动设置。 You can use inherited context and still bind to UserControl properties by using either RelativeSource or ElementName bindings. 您可以使用继承的上下文,并且仍然可以通过使用RelativeSourceElementName绑定来绑定到UserControl属性。

<UserControl ... x:Name="myUserControl">
    <!--  --->
    <ListView ItemsSource="{Binding LogCollection, ElementName=myUserControl}" Name="LogView">

Are you sure that LogCollection that you are actually adding items is the one that you are binding your grid to? 您确定要实际添加项目的LogCollection是将网格绑定到的对象吗? I have created a sample application that has your code but works as expected? 我创建了一个示例应用程序,该应用程序具有您的代码,但按预期运行? Maybe you need to post more of your code. 也许您需要发布更多代码。

Here is my sample application . 这是我的示例应用程序

Maybe your ItemsSource binding is now working at all. 也许您的ItemsSource绑定现在可以正常工作了。 Do you see any binding errors in the console? 您是否在控制台中看到任何绑定错误? Something similar to "BindingExpression path error: 'LogCollection' property not found on 'object'" 类似于“ BindingExpression路径错误:在'object'上找不到'LogCollection'属性”

为什么我的 ListBox 列表与 ObservableCollection 正确绑定<string>但不是 ObservableCollection<object><div id="text_translate"><p> 我有一个列表框:</p><pre> <ListBox ItemsSource="{Binding SupplyGroups}" SelectedItem="{Binding ModelSupplyGroup, Mode=TwoWay}"/></pre><p> SupplyGroups是一个ObservableCollection<SupplyGroup></p><p> SupplyGroup是一个 object ,带有一个int SupplyGroupId和一个string SupplyGroupTitle 。 有一个public override string ToString() ,因此 ListBox 获得要显示的标题。</p><p> ModelSupplyGroup是一个访问模型的 SupplyGroup 的属性。</p><p> 当加载 window 时,保存为ModelSupplyGroup的值不会导致匹配的 ListBox 行被选中。 如果我修改代码, SupplyGroup object 替换为string ,它就能正常工作。 绑定似乎以相反的方向工作,因此如果选择了 ListBox 行,它将正确更新绑定的ModelSupplyGroup 。 检查 ObervableCollection 和 ModelSupplyGroup 中匹配的 SupplyGroup 中的对象,它们具有相同的 ID 和 Title 值。</p><pre> public SupplyGroup ModelSupplyGroup { get { return this.purchasingRepository.GetSupplyGroupById(this.Model.SupplyGroupId); } set { this.Model.SupplyGroup = value; } }</pre><p> GetSupplyGroupById()从 Id 返回完整的 object。</p></div></object></string> - Why does my ListBox List bind correctly with ObservableCollection<string> but not ObservableCollection<object>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我的ObservableCollection没有在ListBox中刷新? - why my ObservableCollection is not refreshed in the ListBox? 为什么ContinueWhenAll隐藏了未观察到的异常 - Why ContinueWhenAll hides unobserved exception 为什么我的ObservableCollection无法更新我的UI? - Why isnt my ObservableCollection updating my UI? 为什么我的ObservableCollection <T> 我的DataGridView没有观察到? - Why is my ObservableCollection<T> not observed by my DataGridView? 为什么我的第二个ObservableCollection获取更新? - Why my second ObservableCollection is getting update? 为什么我的项目中缺少ObservableCollection的所有方法? - Why are all of the methods of an ObservableCollection missing in my project? 为什么我的ObservableCollection序列化不起作用? - Why my ObservableCollection serialization doesn't work? 为什么我的 ListBox 列表与 ObservableCollection 正确绑定<string>但不是 ObservableCollection<object><div id="text_translate"><p> 我有一个列表框:</p><pre> <ListBox ItemsSource="{Binding SupplyGroups}" SelectedItem="{Binding ModelSupplyGroup, Mode=TwoWay}"/></pre><p> SupplyGroups是一个ObservableCollection<SupplyGroup></p><p> SupplyGroup是一个 object ,带有一个int SupplyGroupId和一个string SupplyGroupTitle 。 有一个public override string ToString() ,因此 ListBox 获得要显示的标题。</p><p> ModelSupplyGroup是一个访问模型的 SupplyGroup 的属性。</p><p> 当加载 window 时,保存为ModelSupplyGroup的值不会导致匹配的 ListBox 行被选中。 如果我修改代码, SupplyGroup object 替换为string ,它就能正常工作。 绑定似乎以相反的方向工作,因此如果选择了 ListBox 行,它将正确更新绑定的ModelSupplyGroup 。 检查 ObervableCollection 和 ModelSupplyGroup 中匹配的 SupplyGroup 中的对象,它们具有相同的 ID 和 Title 值。</p><pre> public SupplyGroup ModelSupplyGroup { get { return this.purchasingRepository.GetSupplyGroupById(this.Model.SupplyGroupId); } set { this.Model.SupplyGroup = value; } }</pre><p> GetSupplyGroupById()从 Id 返回完整的 object。</p></div></object></string> - Why does my ListBox List bind correctly with ObservableCollection<string> but not ObservableCollection<object> 为什么我的ObservableCollection不会 <MenuItem> 更新RaisePropertyChanged? - Why won't my ObservableCollection<MenuItem> update on RaisePropertyChanged? 为什么我的测试“propType == typeof(ObservableCollection <string> )“失败了? - Why my test “propType == typeof(ObservableCollection<string>)” fails?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM