查找集合的多个实例中的项目总数&绑定计数到Textblock

时间:2013-09-05 20:34:36

标签: c# wpf linq xaml

正如标题所述,我试图找到ObservableCollection的多个实例中的项目总数,并将结果绑定到Textblock。我设法通过LINQ获得正确的号码......

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

public int GlobalPopulation { get; set; }

...但LINQ与XAML绑定不兼容。初始值显示正确,但不会随计数更改而更新。如果我创建了一个我的viewmodel的新实例,则会显示新的数字,因为再次调用构造函数。我的viewmodel继承自MVVM的ViewModelBase,并通过Kind of Magic实现INPC。我有其他属性被正确绑定并按预期运行,所以这不是问题。

我尝试过使用像OLinq和BindableLinq这样的工具,但没有运气。现在看起来我不得不在没有LINQ的情况下做到这一点,但不幸的是我不知道如何在没有LINQ的情况下检索相同的值并将其绑定到Textblock。如果有人能告诉我一种方法在这种情况下使LINQ绑定工作,或者如何在没有LINQ的情况下实现相同的结果,我将非常感激。

2 个答案:

答案 0 :(得分:1)

很容易忘记您可以自己订阅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();
}

只要GlobalPopulation触发属性更改事件,对结算次数的更改就会传播到用户界面。

(您可能希望将GameContainer实例存储在视图模型上,然后从非静态版本的RecalculateCount引用它,而不是在事件处理lambda中捕获它;该代码旨在是一个简单的演示,但可能隐藏着奇怪的对象生命周期问题。)

答案 1 :(得分:0)

改变这个:

public int GlobalPopulation { get; set; }

到此:

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