C#/WPF:使 GridViewColumn 可见 = false?

问题描述 投票:0回答:7
c# wpf listview visibility gridviewcolumn
7个回答
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>

8
投票

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

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

这是代码。

XAML:

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

布尔到可见性转换器:

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

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

0
投票

一种更简单的方法,仍然使用将列宽度设置为零的概念,但没有使用

IValueConverter
的副作用(用户仍然可以将列拖得更宽),它是创建一个新的 getter/setter 来返回基于您的
ColumnIsVisible
变量的宽度,然后绑定到该变量:

public double ColumnWidth
{
    get
    {
        if (this.ColumnIsVisible)
        {
            return 100;
        }
        else
        {
            return 0;
        }
    }

    set
    {
        OnPropertyChanged("ColumnWidth");
    }
}

使您的绑定为双向,如果用户尝试将列拖得更宽,将调用

OnPropertyChanged
并将宽度重置为0。不过,您可能必须使用绑定代理来进行绑定。当 ColumnIsVisible 更新时,还添加对
OnPropertyChanged("ColumnWidth")
的调用:)


0
投票

我已将该列设置为

width="0"
。 现在该列看起来不可见。但不知道会不会影响其他什么。 这可能是一个虚拟的解决方案,但目前它有效。


0
投票

我选择通过在创建一个新的类来保存GridView的状态,然后在状态发生改变的时候手动更新列表的状态,相当于不可见的时候移除,而不是隐藏他

           foreach (var item in ListViewVisibilitys.Where(x => x.IsVisibility==false).ToList())
            {
                gridView.Columns.Remove(item.gridViewColumn);
            }
            var lists = ListViewVisibilitys.Where(x => x.IsVisibility == true).ToList();
            for (int i = 0; i < lists.Count; i++)
            {
                var desiredColumn = lists[i].gridViewColumn;
                if (gridView.Columns.Contains(desiredColumn))
                {

                    var actualIndex = gridView.Columns.IndexOf(desiredColumn);
                    // 如果当前列的位置不正确,则将其移动到正确的位置
                    if (actualIndex != i)
                    {
                        gridView.Columns.Move(actualIndex, i);
                    }
                }
                else
                {
                    gridView.Columns.Insert(i, desiredColumn);
                }

            }

-1
投票

如果 Thumb.DragDelta 可以解决问题,请使用

我在列表视图中使用它作为

<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;   
 }
}
}
© www.soinside.com 2019 - 2024. All rights reserved.