C# 基于列值隐藏DataGrid列

C# 基于列值隐藏DataGrid列,c#,wpf,xaml,C#,Wpf,Xaml,我有一个带有DataGrid的窗口,我想根据作为DataGrid的ItemSource的ObservableCollection的内容隐藏某些列 基于这个问题: 我写了一篇VisibilityConverter: public class StringLengthVisiblityConverter : IValueConverter { public StringLengthVisiblityConverter() { } public Object Convert(obj

我有一个带有DataGrid的窗口,我想根据作为DataGrid的ItemSource的ObservableCollection的内容隐藏某些列

基于这个问题:

我写了一篇VisibilityConverter:

 public class StringLengthVisiblityConverter : IValueConverter
{
    public StringLengthVisiblityConverter() { }
    public Object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null || value.ToString().Length == 0)
        {
            return Visibility.Collapsed;
        }
        else
        {
            return Visibility.Visible;
        }
    }

    public Object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
以下是XAML:

        <DataGrid.Resources>
            <local:StringLengthVisiblityConverter x:Key="VisConverter"/>
        </DataGrid.Resources>
        <DataGrid.Columns>

            <DataGridTextColumn  Header="Switch Port" Binding="{Binding FCPort}"/>
            <DataGridTextColumn Width="*" Header="WWPN" Binding="{Binding Path=WWPN}" 
                         Visibility="{Binding Path=WWPN, Converter={StaticResource VisConverter}}"/>
            <DataGridTextColumn Header="FCID" Binding="{Binding Path=FCID}"
            Visibility="{Binding Path=FCID, Converter={StaticResource VisConverter}}"/>

        </DataGrid.Columns>
    </DataGrid>


我用WWPN和FCID都为null的类的实例加载了集合。我希望这些列隐藏在datagrid中,但它们仍然可见。我在VisibilityConverter中添加了一个断点,并通过调试器运行了它,但它看起来没有被调用

您需要检查
DataGridTextColumn
中的每个值,并相应地设置
列的可见性。
包装我从DataGrid派生的所有逻辑

public class MyDataGrid : DataGrid
{
    private void ValidateColumnVisibility()
    {
        if (Items.Count == 0 || Items[0] == CollectionView.NewItemPlaceholder) return;
        var itemClass = Items[0].GetType();
        foreach (var column in Columns)
        {
            if (column.GetType() == typeof(DataGridTextColumn))
            {
                // find the property that this column is bound to
                DataGridBoundColumn boundColumn = column as DataGridBoundColumn;
                Binding binding = boundColumn.Binding as Binding;
                string boundPropertyName = binding.Path.Path;
                var prop = itemClass.GetProperty(boundPropertyName);

                // Validating Column.Visibility when first value is null
                // when all values are null -> Visibility.Collapsed
                // bound value not a string -> Visibility.Visible
                // all bound strings empty  -> Visibility.Collapsed
                if (prop.GetValue(Items[0]) == null)
                {
                    column.Visibility = Visibility.Collapsed;
                    foreach (var item in Items)
                    {
                        if (item != CollectionView.NewItemPlaceholder)
                        {
                            if (prop.GetValue(item) != null)
                            {
                                if (prop.GetValue(item).GetType() != typeof(String))
                                    column.Visibility = Visibility.Visible;
                                else if (String.IsNullOrEmpty(prop.GetValue(item) as String) == false)
                                    column.Visibility = Visibility.Visible;
                            }
                        }
                    }
                }

                // First value not null and all bound strings empty -> Visibility.Collapsed
                else if (prop.GetValue(Items[0]).GetType() == typeof(String))
                {
                    column.Visibility = Visibility.Collapsed;
                    foreach (var item in Items)
                    {
                        if (item != CollectionView.NewItemPlaceholder)
                        {
                            if (String.IsNullOrEmpty(prop.GetValue(item) as String) == false)
                                column.Visibility = Visibility.Visible;
                        }
                    }
                }
            }
        }
    }

    protected override void OnItemsSourceChanged(
        IEnumerable oldValue, IEnumerable newValue)
    {
        base.OnItemsSourceChanged(oldValue, newValue);
        ValidateColumnVisibility();
    }

    protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
    {
        base.OnItemsChanged(e);
        ValidateColumnVisibility();
    }
}

使用
MyDataGrid
您不再需要在XAML中自动设置
列。可见性

如果所有项都是空字符串或null,是否隐藏完整列?然后您可以绑定到项(让路径为空)并创建一个多值转换器来迭代您的项。这是因为
DataGridColumn
直接从
DependencyObject
派生,而不是
FrameworkElement
FrameworkContentElement
,因此数据上下文不会被继承。检查输出窗口,您应该能够在那里找到
System.Windows.Data:Error:2
消息。对您的确切问题进行解释和解决方法。@Grx70-谢谢。这就回答了问题。这很干净,我想我会这样做的。它还将清理XAML。