WPF:如何使用XAML隐藏GridViewColumn?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF:如何使用XAML隐藏GridViewColumn?相关的知识,希望对你有一定的参考价值。
我在App.xaml中有以下对象
<Application.Resources>
<ResourceDictionary>
<GridView x:Key="myGridView" x:Shared="false">
<GridViewColumn Header="Created" DisplayMemberBinding="{Binding Path=Created}"/>
... more code ...
我在多个地方使用这个网格视图。例:
<ListView x:Name="detailList" View="{StaticResource myGridView}" ...>
在其中一个用法(例如上面的detailList)中,我想隐藏Created列,可能使用XAML?
有任何想法吗?
答案
实际上,我发现最简单的解决方案是通过附加属性:
public class GridViewColumnVisibilityManager
{
static void UpdateListView(ListView lv)
{
GridView gridview = lv.View as GridView;
if (gridview == null || gridview.Columns == null) return;
List<GridViewColumn> toRemove = new List<GridViewColumn>();
foreach (GridViewColumn gc in gridview.Columns)
{
if (GetIsVisible(gc) == false)
{
toRemove.Add(gc);
}
}
foreach (GridViewColumn gc in toRemove)
{
gridview.Columns.Remove(gc);
}
}
public static bool GetIsVisible(DependencyObject obj)
{
return (bool)obj.GetValue(IsVisibleProperty);
}
public static void SetIsVisible(DependencyObject obj, bool value)
{
obj.SetValue(IsVisibleProperty, value);
}
public static readonly DependencyProperty IsVisibleProperty =
DependencyProperty.RegisterAttached("IsVisible", typeof(bool), typeof(GridViewColumnVisibilityManager), new UIPropertyMetadata(true));
public static bool GetEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(EnabledProperty);
}
public static void SetEnabled(DependencyObject obj, bool value)
{
obj.SetValue(EnabledProperty, value);
}
public static readonly DependencyProperty EnabledProperty =
DependencyProperty.RegisterAttached("Enabled", typeof(bool), typeof(GridViewColumnVisibilityManager), new UIPropertyMetadata(false,
new PropertyChangedCallback(OnEnabledChanged)));
private static void OnEnabledChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
ListView view = obj as ListView;
if (view != null)
{
bool enabled = (bool)e.NewValue;
if (enabled)
{
view.Loaded += (sender, e2) =>
{
UpdateListView((ListView)sender);
};
view.TargetUpdated += (sender, e2) =>
{
UpdateListView((ListView)sender);
};
view.DataContextChanged += (sender, e2) =>
{
UpdateListView((ListView)sender);
};
}
}
}
}
然后,它可以这样使用:
<ListView foo:GridViewColumnVisibilityManager.Enabled="True">
...
<GridViewColumn Header="Status" foo:GridViewColumnVisibilityManager.IsVisible="{Binding ShowStatusColumn}">
<GridViewColumn.CellTemplate>
<DataTemplate> ...
另一答案
<GridViewColumn Width="{Binding Tag, RelativeSource={RelativeSource AncestorType=ListView}, Converter={converters:BooleanToWidthConverter}, ConverterParameter=100}">
<GridViewColumn.HeaderContainerStyle>
<Style TargetType="{x:Type GridViewColumnHeader}" BasedOn="{StaticResource ColumnHeaderStyle}">
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Tag, RelativeSource={RelativeSource AncestorType=ListView}}" Value="true">
<Setter Property="IsEnabled" Value="True"/>
</DataTrigger>
</Style.Triggers>
</Style>
</GridViewColumn.HeaderContainerStyle>
<GridViewColumn.Header>
<StackPanel Tag="columnHeader" Orientation="Horizontal">
</StackPanel>
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
<DataTemplate>
<ContentControl>
<TextBlock Text="test" />
</ContentControl>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
class BooleanToWidthConverter:IValueConverter {
public object Convert (object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool b)
{
return b ? parameter : 0;
}
return 0;
}
public object ConvertBack (object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
遗憾的是,GridViewColumn中没有“IsVisible”属性但是,我有一个解决方案可以通过简单而完整的方式解决这个问题:
- 将宽度设置为0.许多Dev只是在此步骤停止,因为它似乎已被隐藏但不是。我们仍然可以扩展它,因此通过调整大小列将其重新放回UI,因此我们需要做更多的步骤2。
- 通过设置GridViewColumnHeader IsEnabled = false禁用调整GridViewColumn的大小。
上面的代码示例:
另一答案
基于Ben McMillan的回答,但支持动态改变可见属性。我通过删除IsEnabled属性进一步简化了他的解决方案。
public class GridViewColumnVisibilityManager
{
static Dictionary<GridViewColumn, double> originalColumnWidths = new Dictionary<GridViewColumn, double>();
public static bool GetIsVisible(DependencyObject obj)
{
return (bool)obj.GetValue(IsVisibleProperty);
}
public static void SetIsVisible(DependencyObject obj, bool value)
{
obj.SetValue(IsVisibleProperty, value);
}
public static readonly DependencyProperty IsVisibleProperty =
DependencyProperty.RegisterAttached("IsVisible", typeof(bool), typeof(GridViewColumnVisibilityManager), new UIPropertyMetadata(true, OnIsVisibleChanged));
private static void OnIsVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
GridViewColumn gc = d as GridViewColumn;
if (gc == null)
return;
if (GetIsVisible(gc) == false)
{
originalColumnWidths[gc] = gc.Width;
gc.Width = 0;
}
else
{
if (gc.Width == 0)
gc.Width = originalColumnWidths[gc];
}
}
}
另一答案
您最好的选择可能是通过继承GridView类,添加所需的列以及显示有意义的属性来显示/隐藏特定列来创建自定义控件。您的自定义GridView类可能如下所示:
using System;
using System.Windows.Controls;
namespace MyProject.CustomControls
{
public class CustomGridView : GridView
{
private GridViewColumn _fixedColumn;
private GridViewColumn _optionalColumn;
public CustomGridView()
{
this._fixedColumn = new GridViewColumn() { Header = "Fixed Column" };
this._optionalColumn = new GridViewColumn() { Header = "Optional Column" };
this.Columns.Add(_fixedColumn);
this.Columns.Add(_optionalColumn);
}
public bool ShowOptionalColumn
{
get { return _optionalColumn.Width > 0; }
set
{
// When 'False' hides the entire column
// otherwise its width will be set to 'Auto'
_optionalColumn.Width = (!value) ? 0 : Double.NaN;
}
}
}
}
然后你可以像在这个例子中那样从XAML设置该属性:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cc="clr-namespace:MyProject.CustomControls"
Title="Window1"
Height="300"
Width="300">
<StackPanel>
<ListView>
<ListView.View>以上是关于WPF:如何使用XAML隐藏GridViewColumn?的主要内容,如果未能解决你的问题,请参考以下文章