Is there any way to temporarily detach a binding in WPF?

谁说胖子不能爱 提交于 2020-01-05 08:22:52

问题


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!


回答1:


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.



来源:https://stackoverflow.com/questions/1355273/is-there-any-way-to-temporarily-detach-a-binding-in-wpf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!