【问题标题】:EmptyListToVisibilityConverter空列表到可见性转换器
【发布时间】:2018-08-15 01:00:12
【问题描述】:

我正在尝试为 WPF 做一个“空列表到可见性转换器”。 这是一个 IValueConverter ,它接受一个对象(应该是一个列表),如果列表为空(或者如果传递的对象为 null )它应该返回 Visibility.Collapsed;如果列表不为空,则应返回 Visibility.Visibile;

我打算将它用于数据网格。计划是每当提供给 ItemsSource 的列表为空列表或 null 时,使数据网格不可见(折叠)。

<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”是否是一个列表...... . 有什么提示吗?

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

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

【问题讨论】:

  • 嗨,MadSeb。请停止在您的帖子上签名。谨向您和您的孩子致以最诚挚的问候,

标签: wpf binding


【解决方案1】:

您不能将列表转换为 IList ,但可以将其转换为 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}}”>

【讨论】:

    【解决方案2】:

    我想问题是,当您从中添加或删除项目时,集合对象保持不变。所以绑定不会更新值,也不会调用转换器。

    【讨论】:

      【解决方案3】:

      我认为它很简单,给你:

        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();
          }
        }
      

      希望能帮到你,谢谢! - 沙姆

      【讨论】:

        【解决方案4】:

        我的猜测是因为您在转换器中使用了IList&lt;Object&gt;,但您的实际集合是IList&lt;SomethingElse&gt;。看,IList 不是协变的,所以你不能将任何IList&lt;T&gt; 转换为IList&lt;Object&gt;。我的建议是尝试在转换器中使用IEnumerable&lt;object&gt;,并使用 Count() 扩展方法来确定集合中的项目数。

        【讨论】:

        • 我使用“Any”而不是 Count()>0 > ((IEnumerable) value).Any()? Visibility.Visible: Visibility.Collapsed;
        【解决方案5】:

        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;
        }
        

        【讨论】:

          【解决方案6】:

          更好的选择是使用 ObservableCollection,然后绑定到它的 Count 属性:WPF Converters and ObservableCollections

          【讨论】:

            猜你喜欢
            • 2014-03-23
            • 2019-07-17
            • 2013-08-18
            • 2018-05-21
            • 1970-01-01
            • 1970-01-01
            • 2010-12-30
            • 1970-01-01
            • 2019-01-03
            相关资源
            最近更新 更多