C#/WPF:如何将GridViewColumn设置为Visible=false?

19

请问是否有一种选项可以像这样隐藏 GridViewColumn:

<ListView.View>
    <GridView>
        <GridViewColumn Header="Test" IsVisible="{Binding Path=ColumnIsVisible}" />
    </GridView>
<ListView.View>

非常感谢!

编辑:为了更清晰

不幸的是,没有“IsVisible”属性。我正在寻找创建该属性的方法。

编辑:根据反馈提供的解决方案如下:

<GridViewColumn DisplayMemberBinding="{Binding Path=OptionColumn1Text}" 
                Width="{Binding Path=SelectedEntitiy.OptionColumn1Width}">
    <GridViewColumnHeader Content="{Binding Path=SelectedEntitiy.OptionColumn1Header}" IsEnabled="{Binding Path=SelectedEntitiy.OptionColumn1Width, Converter={StaticResource widthToBool}}" />
</GridViewColumn>

public class WidthToBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (int)value > 0;
    }

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

感谢大家!
加油!

6个回答

13

编辑:反映修改后的问题。

创建一个0宽度的列怎么样?编写一个布尔值到宽度IValueConverter,将ColumnIsVisible作为ConverterParmeter传递进去?

 public class BooleanToWidthConverter : IValueConverter {
        public object Convert(object value, Type targetType, 
                              object parameter, CultureInfo culture){
            return ((bool) parameter)? value : 0;
        }
 
        public object ConvertBack(object value, Type targetType, 
                                  object parameter, CultureInfo culture){
            throw new NotImplementedException();
        }
    }

类似于:

<ListView .. >
 <ListView.Resources>
  <BooleanToWidthConverter x:Key="boolToWidth" />
 </ListView.Resources>

 <ListView.View>
    <GridView>
        <GridViewColumn 
                  Header="Test" 
                  Width=
      "{Binding Path=ColumnWidth, 
                Converter={StaticResource boolToWidth}, 
                ConverterParameter=ColumnIsVisible}" />
    </GridView>
 <ListView.View>

谢谢您的快速回复。不幸的是,没有“IsVisible”属性..所以我正在寻找一种创建它的方法。 - Joseph jun. Melettukunnel
1
对您的编辑进行评论:这仍然允许用户调整列的大小,不幸的是也没有启用属性。 - Joseph jun. Melettukunnel
3
GridViewColumn本身没有IsEnabled属性,但是GridViewColumnHeader有一个(IsEnabled)属性(它继承自ButtonBase),所以您可以在HeaderContainerStyle中设置IsEnabled。 - Thomas Levesque
将列宽设置为0,加1。请查看我的回复,其中使用了附加行为的变体。 - Helge Klein
2
将宽度设置为0仍然会使其可扩展,从而将其带回UI界面。 - Yahya
@Yahya 更糟糕的是,如果在将列宽设置为0后手动扩展列宽,绑定会中断。 - Tom Lint

8

这里是另一种基于将列宽设置为零的解决方案。我稍微修改了一下,现在它的工作方式如下:

  1. 使用bool-to-visibility转换器将标题的可见性绑定到ViewModel的布尔属性
  2. 使用标题的附加属性将列的宽度设置为零

以下是代码。

XAML:

<GridViewColumn
    HeaderTemplate="..." 
    HeaderContainerStyle="...">
    <GridViewColumnHeader 
        Content="Header text" 
        Visibility="{Binding AppliesToColumnVisible, Converter={StaticResource BooleanToVisibilityConverter}}" 
        behaviors:GridViewBehaviors.CollapseableColumn="True" />

BooleanToVisibilityConverter:

public class BooleanToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool param = bool.Parse(value.ToString());
        if (param == true)
            return Visibility.Visible;
        else
            return Visibility.Collapsed;
    }

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

附加行为 GridViewBehaviors.CollapseableColumn:

public static readonly DependencyProperty CollapseableColumnProperty =
     DependencyProperty.RegisterAttached("CollapseableColumn", typeof(bool), typeof(GridViewBehaviors),
    new UIPropertyMetadata(false, OnCollapseableColumnChanged));

public static bool GetCollapseableColumn(DependencyObject d)
{
    return (bool)d.GetValue(CollapseableColumnProperty);
}

public static void SetCollapseableColumn(DependencyObject d, bool value)
{
    d.SetValue(CollapseableColumnProperty, value);
}

private static void OnCollapseableColumnChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
    GridViewColumnHeader header = sender as GridViewColumnHeader;
    if (header == null)
        return;

    header.IsVisibleChanged += new DependencyPropertyChangedEventHandler(AdjustWidth);
}

static void AdjustWidth(object sender, DependencyPropertyChangedEventArgs e)
{
    GridViewColumnHeader header = sender as GridViewColumnHeader;
    if (header == null)
        return;

    if (header.Visibility == Visibility.Collapsed)
        header.Column.Width = 0;
    else
        header.Column.Width = double.NaN;   // "Auto"
}

不错。我将这段代码放入自定义控件的代码后台,"GridViewBehaviors" 就成为了控件类名。请注意,在第一次编译代码后,你可能会遇到智能感知错误。 - Andrew Roberts

1
你可以通过编程来删除它:
如果你知道标题的名称:
RemoveHeaderByName(listView, "Your Header Name");

private bool RemoveHeaderByName(ListView listView, string headerName)
{
    GridView gridView = listView?.View as GridView;
    if (gridView != null)
    {
        foreach(var column in gridView?.Columns)
        {
            if (column.Header as string == headerName)
            {
                if(gridView.Columns.Remove(column))
                    return true;
            }
        }
        return false;
    }
}

或者如果您知道标题的索引(如果标题名称可以更改,例如如果您有本地化应用程序,则更好):

private bool RemoveHeaderByPosition(ListView listView, int position)
{
    GridView gridView = listView?.View as GridView;
    if (gridView != null && position >= gridView.Columns.Count-1)
    {
        var columnToRemove = gridView.Columns[position];
        if (gridView.Columns.Remove(columnToRemove))
            return true;
    }
    return false;
}

关于在程序中操纵 GridView 列的警告。这样做非常方便,你可以通过操纵 ObservableCollection 的内容在程序中移除、插入或移动列。然而,如果在网格显示后向集合中添加列,将会破坏列表虚拟化,并在滚动时导致明显的性能下降。 - undefined

0

我已将该列的width="0"设置为零。 现在该列看起来好像不可见。但我不知道它是否会影响其他任何东西。 这可能是一个虚拟解决方案,但目前它可以工作。


4
用户仍然可以拖动列宽。 - paparazzo

0
一个更简单的方法,仍然使用将列宽度设置为零的概念,但不具有使用 IValueConverter 的副作用(用户仍然可以拖动列变宽),是创建一个新的 getter/setter,根据您的 ColumnIsVisible 变量返回宽度,然后绑定到它:
public double ColumnWidth
{
    get
    {
        if (this.ColumnIsVisible)
        {
            return 100;
        }
        else
        {
            return 0;
        }
    }

    set
    {
        OnPropertyChanged("ColumnWidth");
    }
}

将您的绑定设置为TwoWay,如果用户尝试拖动列宽,则会调用OnPropertyChanged并将宽度重置为0。您可能需要使用绑定代理来进行绑定。此外,在每次更新ColumnIsVisible时,请添加对OnPropertyChanged(“ColumnWidth”)的调用 :)

-1

如果使用Thumb.DragDelta可能会解决问题

我在ListView中使用它,如下所示:

<ListView x:Name="MyListView"IsSynchronizedWithCurrentItem="True"   
      ItemsSource="{Binding Path=Items}",  Mode=Default, Source={StaticResource DataProvider}}" 
      Thumb.DragDelta="Thumb_DragDelta">


public Window1()
{   
InitializeComponent(); 
MyListView.AddHandler(Thumb.DragDeltaEvent, new DragDeltaEventHandler(Thumb_DragDelta), true );

void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
{  
 Thumb senderAsThumb = e.OriginalSource as Thumb;    
 GridViewColumnHeader header = senderAsThumb.TemplatedParent as GridViewColumnHeader;     
 if (header.Column.ActualWidth < MIN_WIDTH)   
 {   
    header.Column.Width = MIN_WIDTH;  
 }  
 if (header.Column.ActualWidth > MAX_WIDTH)     
 {      
    header.Column.Width = MAX_WIDTH;   
 }
}
}

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