2014-10-10 114 views
1

我有一个从CollectionViewGroup动态构建的ControlTemplate。WPF绑定Visiblity到集合属性

我希望它的可见性只有在所有项目的某个属性设置为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."); 
    } 
} 

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

我该如何完成上述操作,但是让绑定动态监视所有的项目属性更改?

+1

@KingKing对他不会有任何好处;该绑定是针对**收集实例**的,所以只有当'Items'设置为新集合时才会调用转换器。如果集合发生更改,或者集合中的项目的某些属性发生更改,则绑定引擎不知道它应该重新评估绑定。 – 2014-10-10 18:02:25

回答

1

这里的问题是,你对集合实例结合,所以绑定如果当你分配一个新的集合Items才会重新评估。据推测,你只设置了Items一次,所以转换器只会被调用一次。当集合被修改时它不会被调用,也不会在集合中的项目被修改时被调用。 WPF绑定不支持这些“深层”依赖关系,因此您需要找到不同的方法。

我建议在您的视图模型上维护一个单独的属性,例如AllItemsAccepted,您可以直接绑定它。您可以听取Items上的增加,删除和替换,并倾听Items中任何元素的属性更改。发生这种变化时,您必须重新评估AllItemsAccepted。不要忘记提出物业更改通知,以便对AllItemsAccepted上的任何绑定进行重新评估。

注意这里的概念的MultiBinding(和IMultiValueConverter),但这些都是如果正在针对已知的结合,固定的一组值(例如,两个或更多个单独的属性)的唯一有用的;他们不会帮助你获得动态收藏。我只是把它们拿起来,以免你掉下一个兔子洞并空着。

+0

感谢您的答案迈克。 我的问题是,我有很多这些动态创建的按钮,他们都有自己的一套项目(他们本质上是一个集合的组风格),所以我不能有一个静态他们之间的变量来决定可见性。 虽然也许我误解了你。 – nextint 2014-10-10 19:02:32

+0

您问题中的转换器会评估是否所有项目都被接受;你只需要自己评估一下,把结果放在一个可访问的地方(比如'Items'旁边),并且保持最新状态。基本上,你自己要做的是你希望绑定为你做什么。 – 2014-10-10 19:15:23

+0

很抱歉对已故的评论,但我撤回了我的投票,因为我认为你试图冷静地谈论实际上是问题的部分,而不是冒犯。我只是不想混淆任何其他读者。对于未来的读者,我认为迈克已经误解了这个问题,这是没有价值的。 – nextint 2014-10-17 13:21:04