我将ObservableCollection绑定到一个控件,该控件有一个转换器,可以根据集合是否有值来更改其可见性:
简化示例:
XAML:
<Window.Resources>
<local:MyConverter x:Key="converter"/>
</Window.Resources>
<Grid x:Name="grid">
<Rectangle Height="100" Width="200" Fill="CornflowerBlue"
Visibility="{Binding Converter={StaticResource converter}}"/>
<Button Content="click"
HorizontalAlignment="Left" VerticalAlignment="Top"
Click="Button_Click"/>
</Grid>
C#:
ObservableCollection<string> strings;
public MainWindow()
{
InitializeComponent();
strings = new ObservableCollection<string>();
grid.DataContext = strings;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
strings.Add("new value");
}
绑定集合时,有值时矩形可见,而集合为空时矩形不可见。但是,如果集合为空,并且我在运行时添加了一个值,则Rectangle不会出现(转换器的Convert方法甚至不会启动)。我是错过了什么,还是只是想问太多IValueConverter?
好的,下面是我如何使用MultiValueConverter
解决这个问题
转换器现在看起来像:
public object Convert(
object[] values,
Type targetType,
object parameter,
System.Globalization.CultureInfo culture)
{
ObservableCollection<string> strings =
values[0] as ObservableCollection<string>;
if (strings == null || !strings.Any())
return Visibility.Collapsed;
else
return Visibility.Visible;
}
public object[] ConvertBack(
object value,
Type[] targetTypes,
object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
XAML现在看起来像:
<Rectangle Height="100" Width="200" Fill="CornflowerBlue">
<Rectangle.Visibility>
<MultiBinding Converter="{StaticResource converter}">
<Binding Path="."/>
<Binding Path="Count"/>
</MultiBinding>
</Rectangle.Visibility>
</Rectangle>
C#保持不变:)
我认为,如果绑定源已更新并通知该更新(作为DependencyProperty或使用INotifyPropertyChanged),则始终调用绑定中的转换器。但是,如果添加或删除了项,则ObservableCollection不会引发PropertyChanged事件,而是引发CollectionChanged事件。如果集合中的某个项发生更改,则它根本不会引发任何事件。即使项本身引发PropertyChanged,这也不会更新集合上的Binding,因为Binding源不是项,而是集合。
我担心你的方法不会这样奏效。您可以直接绑定到ObservableCollection.Count,并向其添加适当的数学转换器来执行反转和乘法,但Count属性不执行更改通知,因此没有选项。我认为您必须在ViewModel或代码后面提供另一个属性来处理这些情况。。。
问候,
创建集合后必须设置DataContext;很可能您将"string"集合初始化为"null",将构造函数中的DataContext设置为该值(例如null),然后实际创建集合——这样,DataContext将保持为null。
创建集合后,必须再次设置DataContext。