I have the following object in App.xaml
This works for me
Need to bind the Visibility on both the header and the content
In this case it is at the end so I don't worry about the Width
BUT the user does not get a UI hook to reset the width so if you set the width to zero it is gone
<GridViewColumn Width="60">
<GridViewColumnHeader HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch"
Visibility="{Binding Source={x:Static Application.Current}, Path=MyGabeLib.CurUser.IsInRoleSysAdmin, Converter={StaticResource bvc}}">
<TextBlock>WS<LineBreak/>Count</TextBlock>
</GridViewColumnHeader>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=WordScoreCount, StringFormat={}{0:N0}}" HorizontalAlignment="Right"
Visibility="{Binding Source={x:Static Application.Current}, Path=MyGabeLib.CurUser.IsInRoleSysAdmin, Converter={StaticResource bvc}}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
In a small utility I wrote, I have a list view where the user can hide/show some columns. There is no Visibility property on the columns, so I decided to set the hidden columns width to zero. Not ideal, as the user can still resize them and make them visible again.
Anyway, to do this, I used:
<GridViewColumn.Width>
<MultiBinding Converter="{StaticResource WidthConverter}" Mode="TwoWay">
<Binding Path="ThreadIdColumnWidth" Mode="TwoWay" />
<Binding Path="IsThreadIdShown" />
</MultiBinding>
</GridViewColumn.Width>
IsThreadIdShown
is bound to a check box on the toolbar.
And the multi-value converter is:
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
if (values.Length != 2) {
return null;
}
object o0 = values[0];
object o1 = values[1];
if (! (o1 is bool)) {
return o0;
}
bool toBeDisplayed = (bool) o1;
if (! toBeDisplayed) {
return 0.0;
}
if (! (o0 is double)) {
return 0;
}
return (double) o0;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
return new object[] { (double)value, Binding.DoNothing };
}
You best bet is probably to create a custom control by inheriting from the GridView class, adding the required columns, and exposing a meaningful property to show/hide a particular column. Your custom GridView class could look like this:
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;
}
}
}
}
Then you can simply set that property from XAML like in this example:
<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>
<cc:CustomGridView ShowOptionalColumn="False" />
</ListView.View>
</ListView>
<ListView>
<ListView.View>
<cc:CustomGridView ShowOptionalColumn="True" />
</ListView.View>
</ListView>
</StackPanel>
</Window>
Optionally, you could make the 'CustomGridView.ShowOptionalColumn' a DependencyProperty to be able to use it as a binding target.
This is my code , it works very well in my project. if you don't like to add some external code.
/// <summary>
/// show/hide datagrid column
/// </summary>
/// <param name="datagrid"></param>
/// <param name="header"></param>
private void ToggleDataGridColumnsVisible()
{
if (IsNeedToShowHideColumn())
{
foreach (GridViewColumn column in ((GridView)(this.ListView1.View)).Columns)
{
GridViewColumnHeader header = column.Header as GridViewColumnHeader;
if (header != null)
{
string headerstring = header.Tag.ToString();
if (!IsAllWaysShowingHeader(headerstring ) )
{
if (IsShowingHeader())
{
}
else
{
//hide it
header.Template = null;
column.CellTemplate = null;
column.Width = 0;
}
}
}
}
}
}