编辑:反映修改后的问题。
创建一个 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>
这里是另一种基于将列宽度设置为零的解决方案。我稍微修改了一下。现在它的工作原理如下:
这是代码。
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"
}
您可以通过编程方式删除它:
如果您知道标题的名称:
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;
}
一种更简单的方法,仍然使用将列宽度设置为零的概念,但没有使用
IValueConverter
的副作用(用户仍然可以将列拖得更宽),它是创建一个新的 getter/setter 来返回基于您的 ColumnIsVisible
变量的宽度,然后绑定到该变量:
public double ColumnWidth
{
get
{
if (this.ColumnIsVisible)
{
return 100;
}
else
{
return 0;
}
}
set
{
OnPropertyChanged("ColumnWidth");
}
}
使您的绑定为双向,如果用户尝试将列拖得更宽,将调用
OnPropertyChanged
并将宽度重置为0。不过,您可能必须使用绑定代理来进行绑定。当 ColumnIsVisible 更新时,还添加对 OnPropertyChanged("ColumnWidth")
的调用:)
我已将该列设置为
width="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);
}
}
如果 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;
}
}
}