在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。
答案 0 :(得分:2)
这是因为CollectionView
实现了ICollectionChanged
,当集合中的项发生变化时会触发ItemsControl
。 IPropertyChanged
查找此事件并做出适当的反应。 A&#34;正常&#34;控制侦听CollectionView
确实实现的CollectionChanged
通知,但不会触发对基础集合的更改。因此,您的绑定永远不会被通知更改。
你可以&#34;勾解&#34; PropertyChanged
事件并使用绑定发送相应的NAME
事件,但此时可能更容易自行更改可见属性。