空列表转可见性转换器

7
我正在尝试为WPF创建一个“空列表到可见性转换器”。 这是一个IValueConverter,它接受一个对象(应该是一个列表),如果列表为空(或传递的对象为空),则应返回Visibility.Collapsed;如果列表不为空,则应返回Visibility.Visible。
我计划在datagrid中使用此功能。计划是当传递给ItemsSource的列表为空列表或为空时,使datagrid不可见(折叠)。
<my:DataGrid 
                    Name="dataGridAuxiliaryTools"
                    Style="{StaticResource DataGridStyle}"
                    CellStyle="{StaticResource DataGridCellStyle}"
                    ColumnHeaderStyle="{StaticResource DataGridColumnHeaderStyle}"
                    ItemsSource="{Binding Path=Items}"
                    IsReadOnly="False"
                    Visibility="{Binding Path=Items, 
                    Converter={StaticResource emptyListToVisibilityConverter}}"
 </my:DataGrid>

我写的EmptyListToVisibilityConverter如下所示:
public class EmptyListToVisibilityConverter : IValueConverter
    {
    public object Convert(object value, Type targetType, object parameter,
                          CultureInfo culture)
    {
        if (value == null)
        {
            return Visibility.Collapsed;
        }
        else if (value is IList<Object>)
        {
            if ((value as IList<Object>).Count == 0)
            {
                return Visibility.Collapsed;
            }
            else
            {
                return Visibility.Visible;
            }
        }
        else
        {
            return Visibility.Visible;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter,
                              CultureInfo culture)
    {
        throw new NotImplementedException();
    }

当 Items 参数为 null 时,这个代码可以正常工作。但是,当 Items 参数为 List 时,不能正常工作...... 我认为下面的代码不正确,不能检测 "value" 是否为 list ...... 有什么提示吗?

if (value is IList<Object>)
            {
                if ((value as IList<Object>).Count == 0)
                {
                    return Visibility.Collapsed;
                }
                else
                {
                    return Visibility.Visible;
                }

有没有关于如何做到这一点的提示?

嗨,MadSeb。请停止在您的帖子中签名。此致问候,祝您和您的孩子们一切顺利。 - Lightness Races in Orbit
6个回答

12

你无法将列表转换为 IList <Object>,但你可以将其转换为 ICollection,然后使用 ICollection.Count:参见http://devw.wordpress.com/2011/07/18/empty-list-visibility-converter/

public class EmptyListVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return Visibility.Collapsed;
        else
        {
            ICollection list = value as ICollection;
            if (list != null)
            {
                if (list.Count == 0)
                    return Visibility.Collapsed;
                else
                    return Visibility.Visible;
            }
            else
                return Visibility.Visible;
        }
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

    {
        throw new NotImplementedException();
    }
}
<ListBox x:Name=”NameChoiceListBox”
         ItemsSource=”{Binding NamesList}”
         SelectedItem=”{Binding SelectedName, Mode=TwoWay}”
         ItemTemplate=”{StaticResource DataTemplateNameChoice}”
         Visibility=”{Binding NamesList, Converter={StaticResource EmptyListVisibilityConverter}}”>

5

我认为这很简单,给你:

  public class NullOrEmptyCollectionToVisibilityConverter : IValueConverter
  {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
      if (value == null) return Visibility.Collapsed;

      var collection = value as ICollection;
      return collection != null ? (collection.Count == 0 ? Visibility.Collapsed : Visibility.Visible) : Visibility.Visible;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
      throw new NotImplementedException();
    }
  }

希望能帮到您,谢谢!- Shams

5
我猜问题在于,当你向集合对象添加或删除项时,该集合对象保持不变。因此,绑定不会更新值,转换器也不会被调用。

2

C# 7版本支持模式匹配。现在你可以这样写:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    switch (value)
    {
        case null:
            return Visibility.Collapsed;
        case ICollection list:
            return list.Count == 0 ? Visibility.Collapsed : Visibility.Visible;
    }

    return Visibility.Visible;
}

2
我的猜测是,这可能是因为您在转换器中使用了 IList<Object>,但实际集合是 IList<SomethingElse>。IList 不是协变的,因此您不能将任何 IList<T> 直接转换为 IList<Object>。我的建议是尝试在转换器中使用 IEnumerable<object>,并使用 Count() 扩展方法来确定集合中的项目数。

我使用了"Any"而不是Count()>0 > ((IEnumerable<object>) value).Any()? Visibility.Visible: Visibility.Collapsed; - TobyEvans

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接