简体   繁体   English

在集合的多个实例中查找项目总数,并将其绑定到Textblock

[英]Finding total number of items in multiple instances of a collection & binding count to Textblock

As the title states, I am trying to find the total number of items in multiple instances of an ObservableCollection and bind the result to a Textblock . 如标题所示,我试图在ObservableCollection多个实例中查找项目总数,并将结果绑定到Textblock I managed to get the correct number via LINQ... 我设法通过LINQ获得了正确的号码...

public WorldViewModel(GameContainer container)
{
    GlobalPopulation = container.Regions
            .SelectMany(x => x.Settlements)
            .SelectMany(x => x.Population)
            .Distinct()
            .Count();
}

public int GlobalPopulation { get; set; }

... but LINQ doesn't work well with XAML binding. ...但是LINQ在XAML绑定中不能很好地工作。 The initial value displays properly but doesn't update as the count changes. 初始值可以正确显示,但不会随着计数的变化而更新。 If I create a new instance of my viewmodel, the new number displays since the constructor is being called again. 如果创建视图模型的新实例,则将显示新数字,因为将再次调用构造函数。 My viewmodel inherits from MVVM's ViewModelBase and implements INPC via Kind of Magic. 我的视图模型继承了MVVM的ViewModelBase,并通过Kind of Magic实现了INPC。 I have other properties that are bound properly and behave as expected, so that's not the issue. 我还具有其他属性,这些属性已正确绑定并表现出预期的效果,所以这不是问题。

I have tried using tools like OLinq and BindableLinq with no luck. 我尝试过使用OLinq和BindableLinq之类的工具,但是没有运气。 Right now it's looking like I'll have to do this without LINQ, but unfortunately I don't know how to, without LINQ, retrieve the same value and bind it to the Textblock . 现在看来,我必须在没有LINQ的情况下执行此操作,但是不幸的是,如果没有LINQ,我不知道如何检索相同的值并将其绑定到Textblock If anybody could either show me a way to make the LINQ binding work in this situation or how to achieve the same result without LINQ, I would greatly appreciate it. 如果有人可以告诉我一种在这种情况下使LINQ绑定起作用的方法,或者在没有LINQ的情况下如何实现相同的结果,我将不胜感激。

It's easy to forget that you can subscribe to the changes in your ObservableCollection yourself: 很容易忘记,您可以自己订阅ObservableCollection的更改:

// not production-quality code
public WorldViewModel(GameContainer container)
{
    foreach (var region in container.Regions)
    {
        region.CollectionChanged += (s,e) => RecalculateCount(container);
        foreach(var settlement in region.Settlements)
        {
            settlement.CollectionChanged += (s,e) => RecalculateCount(container);
            foreach( var population in settlement.Population)
            {
                population.CollectionChanged += (s,e) => RecalculateCount(container);
            }        
        }
    }

    RecalculateCount();
}

private static void RecalculateCount(GameContainer container)
{
    GlobalPopulation = container.Regions
                .SelectMany(x => x.Settlements)
                .SelectMany(x => x.Population)
                .Distinct()
                .Count();
}

So long as GlobalPopulation is firing property changed events, changes to the count of settlements will be propagated to the UI. 只要GlobalPopulation触发属性更改事件,对结算数量的更改将传播到UI。

(You'll probably want to store the GameContainer instance on your view model and then reference it from a non-static version of RecalculateCount, rather than capturing it in the event handling lambda; that code is intended to be a drop-in demo, but probably has strange object lifetime issues hiding in it.) (您可能希望将GameContainer实例存储在视图模型上,然后从GameContainer的非静态版本中引用它,而不是在事件处理lambda中捕获它;该代码旨在作为GameContainer演示,但其中可能隐藏着奇怪的对象生命周期问题。)

Change this: 更改此:

public int GlobalPopulation { get; set; }

to this: 对此:

private int _globalPopulation;
public int GlobalPopulation 
{ 
    get { return _globalPopulation; }
    set
    {
        _globalPopulation = value;
        NotifyPropertyChange("GlobalPopulation");
    }
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM