为什么绑定CollectionView到Window.Visibility不起作用,绑定到相同的绑定属性适用于ItemsControl?

时间:2016-01-15 15:15:13

标签: c# wpf xaml data-binding

在ItemsControl绑定工作之下,当刷新collectionview时,相应地刷新控件中的工具栏。但是,可见性绑定不起作用(甚至一次)并且永远不会调用转换器。输出窗口没有错误。

<Window.Resources>
    <xpui:IEnumerableHasItemsToVisibilityConverter x:Key="IEnumerableHasItemsToVisibilityConverter" />
    <ContextMenu x:Key="ToolbarContextMenu">
        <MenuItem Header="Move to top" Click="MoveToTopClick" />
        <MenuItem Header="Move to left" Click="MoveToLeftClick"/>
    </ContextMenu>
    <xpui:MenuItemToToolbarConverter x:Key="menutotoolbarconverter" />
</Window.Resources>
<ItemsControl Name="Toolbars" ItemsSource="{Binding GuiItemsInstance.FloatingToolbarsView}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ContentControl Content="{Binding Converter={StaticResource menutotoolbarconverter}, ConverterParameter={StaticResource ToolbarContextMenu}}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
<Window.Visibility>
    <Binding Path="GuiItemsInstance.FloatingToolbarsView"  Converter="{StaticResource IEnumerableHasItemsToVisibilityConverter}"/>        
</Window.Visibility>

在GuiItems-singleton(GuiItemsInstance是ViewModel的属性)中实现INotifyPropertyChanged

    public CollectionView FloatingToolbarsView
    { 
        get; 
        private set; 
    }

    //I also tried to bind directly to FloatVisibility:
    private Visibility _floatVisibility = Visibility.Hidden;
    public Visibility FloatVisibility
    {
        get { return _floatVisibility; }
        set
        {
            _floatVisibility = value;
            // Sets the property value. Raises the PropertyChanged event, if needed.
            SetValue(ref _floatVisibility, value);
        }
    }

    ///Event of changes in underlying toolbar collection is handled like this
    private void RefreshFloatingToolbars(int RoleId)
    {
        ActiveRoleId = RoleId;
        FloatingToolbarsView.Refresh();

        if (ToolbarItems.Any(i => i.ToolbarLocation == ToolbarLocation.Float && i.RoleId == RoleId))
            FloatVisibility = Visibility.Visible;
        else
            FloatVisibility = Visibility.Hidden;
    }

转换器:

public class IEnumerableHasItemsToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        if (value != null)
        {
            if (((IEnumerable)value).GetEnumerator().MoveNext())
                return Visibility.Visible;
        }
        return Visibility.Hidden;
    }

视图模型:

//WindowViewModel implements INotifyPropertyChanged
public class FloatingToolbarWindowViewModel : WindowViewModel
{
    public GuiItems GuiItemsInstance { get; set; }

    public FloatingToolbarWindowViewModel(GuiItems guiItems)
    {
        GuiItemsInstance = guiItems;
        GuiItemsInstance.Host = Host;
    }
}

这不起作用,尝试也像这样绑定到ItemsControl本身:

<Window.Visibility>
    <Binding Path="ItemsSource" ElementName="Toolbars"  Converter="{StaticResource IEnumerableHasItemsToVisibilityConverter}"/>        
</Window.Visibility>

导致转换器被调用,其值为null。

1 个答案:

答案 0 :(得分:2)

这是因为CollectionView实现了ICollectionChanged,当集合中的项发生变化时会触发ItemsControlIPropertyChanged查找此事件并做出适当的反应。 A&#34;正常&#34;控制侦听CollectionView确实实现的CollectionChanged通知,但不会触发对基础集合的更改。因此,您的绑定永远不会被通知更改。

你可以&#34;勾解&#34; PropertyChanged事件并使用绑定发送相应的NAME事件,但此时可能更容易自行更改可见属性。