我有一个带有DataGrid的窗口,我希望根据ObservableCollection的内容隐藏某些列,这些内容是DataGrid的ItemSource。
基于这个问题: Conditional element in xaml depending on the binding content
我写了一篇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。我希望这些列隐藏在数据网格中,但它们仍然可见。我在VisbilityConverter中添加了一个断点并通过调试器运行它,但它看起来不像是被调用了。
答案 0 :(得分:1)
您需要检查DataGridTextColumn
中的每个值并相应地设置Column.Visibility
。
包装我从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中设置Column.Visibility
,因为它会自动发生。