【问题标题】:WPF Binding Visiblity to Collection PropertyWPF 将可见性绑定到集合属性
【发布时间】:2014-10-10 17:10:07
【问题描述】:

我有一个从 CollectionViewGroup 动态构建的 ControlTemplate。

我希望只有当所有项目的某个属性都设置为 true 时,它​​的可见性才为 true。我通过以下方式在某种程度上实现了这一点:

XAML

<Button Visibility="{Binding Path=Items, Converter={StaticResource AllAcceptedToVis}}" Click="Button_ShipmentComplete_Click" Width="150" Margin="100,0,0,0">Complete</Button>

C#

public class AllAcceptedToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var items = (IEnumerable<object>)value;

        return items.Cast<MyObject>().All(m => m.Accepted) ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new InvalidOperationException("AllAcceptedToVisibilityConverter can only be used OneWay.");
    }
}

这有效,但仅在加载时有效。它在初始创建后不检查更改,我怀疑是因为它绑定到地址列表(项目)而不是属性,所以它实际上检测到地址列表中没有任何更改(它们保持不变)。

我怎样才能完成上述操作,但让绑定动态监控所有 Items 属性的变化?

【问题讨论】:

  • @KingKing 这对他没有任何好处;该绑定针对集合实例,因此只有当Items 设置为新集合时才会调用转换器。绑定引擎不知道如果集合更改或集合中某个项目的某些属性发生更改,它应该重新评估绑定。

标签: c# wpf list xaml binding


【解决方案1】:

这里的问题是您正在绑定 collection 实例,因此该绑定只会在您将 新集合 分配给 Items 时重新评估。据推测,您只设置了一次Items,因此转换器只会被调用一次。修改集合时不会调用它,也不会在修改集合中的项时调用它。 WPF 绑定不支持那些“深度”依赖,因此您需要找到不同的方法。

我建议在您的视图模型上维护一个单独的属性,例如,AllItemsAccepted,您可以直接绑定到该属性。您可以在Items 上监听添加、删除和替换,并监听Items 中任何元素的属性更改。发生此类更改时,您必须重新评估AllItemsAccepted。不要忘记发出属性更改通知,以便重新评估 AllItemsAccepted 上的任何绑定。

请注意,一个MultiBinding(和IMultiValueConverter)的概念,但只有在绑定已知、固定的一组值时,它们才有用 strong>(例如,两个或多个单独的属性);他们不会帮助您进行动态收藏。我只是为了防止你掉进兔子洞然后空出来。

【讨论】:

  • 感谢迈克的回答。我的问题是我有许多动态创建的按钮,它们都有自己的一组项目(它们本质上是集合组的组样式),所以我不能有一个静态变量之间他们都决定知名度。也许我误解了你。
  • 您问题中的转换器评估是否所有项目都被接受;您只需要自己评估,将结果放在可访问的属性中(例如,在Items 旁边),并保持最新。基本上,做你自己期望绑定为你做的事情。
  • 很抱歉评论晚了,但我撤回了我的投票,因为我认为您正试图冷静地讨论实际上是问题的部分,无意冒犯。我只是不想让其他读者对此感到困惑。对于未来的读者,我相信迈克误解了这个问题,这没有任何价值。
  • 你认为我误解了什么?使用Binding 没有任何实用的方法可以实现您想要的。如果要绑定取决于集合中项目状态的值,则需要自己生成该值。 WPF 绑定没有那么复杂。
  • 谢谢迈克。然后我误解了你的评论,不想欺骗其他人认为这是可行的。这是一个很大的项目,我正在努力将其投入其中,我只是不认为它是为此而设置的。问题是,虽然我正在使用一种类型的项目,但它有两种单独的分组样式(取决于项目属性),并且一旦进入该组,我无法单独控制组样式与该组的实例相比的功能项目。