Reputation: 42354
Background:
I have a ListView
/GridView
with several columns. In some situations, only some of the columns are shown. Since there is no Visible
property for GridViewColumns
in WPF, I set the width of the columns I want to hide to zero. Visually, this achieves the desired effect (and I actually modified the ControlTemplate
for the GridViewColumnHeader
so that it's impossible for the user to accidentally expand any hidden columns).
Problem:
The problem is that the bindings for the hidden columns are still in play, and they are trying to look up data that doesn't exist. In this case, it causes an IndexOutOfRangeException
since it's trying to look up a column name that doesn't exist on the DataTable
that it is bound to.
Question:
How can I temporarily disable or detach the binding for columns that are hidden? Or please suggest a better solution if you have one.
Thanks!
Upvotes: 2
Views: 2219
Reputation: 42354
Ahh, I think I've got it. IValueConverter
to the rescue.
Here's the solution I came up with in case someone else has the same problem:
Step 1. Create a converter.
This IValueConverter
checks whether the index was out of range, and if so, returns an empty string. Note that I use the converter's parameter
to hold the column name.
public class DataRowViewToCellString : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
DataRowView row = (DataRowView)value;
string columnName = (string)parameter;
if (row.DataView.Table.Columns.Contains(columnName))
return row[columnName].ToString();
else
return Binding.DoNothing;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return Binding.DoNothing;
}
}
Step 2. Throw the converter into a DataTemplate
.
<local_converters:DataRowViewToCellString
x:Key="TaskWindow_DataRowViewToCellString" />
<DataTemplate
x:Key="TaskWindow_Column4Template">
<TextBlock
Text="{Binding Converter={StaticResource TaskWindow_DataRowViewToCellString}, ConverterParameter=Column4}" />
</DataTemplate>
Step 3. reference the template in the "sometimes hidden" GridViewColumn
.
<ListView ... >
<ListView.View>
<GridView ... >
...
<GridViewColumn
Header="SometimesHiddenColumn"
CellTemplate="{StaticResource TaskWindow_Column4Template}">
</GridView>
</ListView.View>
</ListView>
EDIT
Change the return value of the converter in cases where the column name is out of range from string.Empty to Binding.DoNothing per Dennis Roche's suggestion.
Upvotes: 3