Преобразователь видимости WPF не срабатывает

Кажется, я не могу заставить работать конвертер видимости. Я думаю, проблема в том, что я устанавливаю соответствующее свойство в конструкторе, поэтому оно не подбирает его по строке. Код ниже, какие-либо предложения относительно того, как я могу это исправить?

MainWindowViewModel: (это главная страница; нажатие кнопки открывает второе окно)

var newWindow = new SecondaryWindow
                {
                    Title = title,
                    DataContext = new SecondaryWindowViewModel{MyData = data, ShowAdditionalColumns = false}
                };
newWindow.Show();

Дополнительное окно: вот соответствующий XAML:

    <Window.Resources>
        <myApp:DataGridVisibilityConverter x:Key="gridVisibilityConverter" />
    </Window.Resources>

<DataGrid ItemsSource="{Binding Path=MyData}" AutoGenerateColumns="False" >
                <DataGrid.Columns>
                    <DataGridCheckBoxColumn Header="Print" Binding="{Binding Path=IsSelected}"/>
                    <DataGridTextColumn Header="FirstName" Binding="{Binding Path=FirstName}" IsReadOnly="True"/>
                    <DataGridTextColumn Header="LastName" Binding="{Binding Path=LastName}" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Lines" Binding="{Binding Path=TotalLines}" IsReadOnly="True" Visibility="{Binding Path=ShowAdditionalColumns, Converter={StaticResource gridVisibilityConverter}}"/>

И вторичный код ViewModel:

private bool showAdditionalColumns;
public bool ShowAdditionalColumns
{
    get { return showAdditionalColumns; }
    set
    {
        showAdditionalColumns= value;
        NotifyPropertyChanged(() => ShowAdditionalColumns);
    }
}

Вот преобразователь; довольно стандартные вещи здесь. Я поставил точку останова в методе convert; и он никогда не попадал:

[ValueConversion(typeof(bool), typeof(Visibility))]
public class DataGridVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var booleanValue = (bool)value;
        return booleanValue ? Visibility.Visible : Visibility.Hidden;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

person Jim B    schedule 12.02.2014    source источник
comment
Пожалуйста, покажите код конвертера видимости.   -  person Will Custode    schedule 12.02.2014
comment
Поскольку объект не полностью построен, когда свойство установлено, ничто не может прослушивать событие изменения свойства. Несколько сумасшедших идей: есть ли причина, по которой ShowAdditionalColumns не может быть свойством Dependency? Я верю, что это решит проблему. Или вы можете настроить обработчик для события DataContextChanged SecondaryWindow и установить свойство в обработчике...   -  person    schedule 12.02.2014
comment
Окно вывода жалуется на что-нибудь? Другие DataGridTextColumn связываются правильно?   -  person Mat J    schedule 12.02.2014
comment
NotifyPropertyChanged(() => ShowAdditionalColumns); Что он делает.. Покажите реализацию PropertyChanged..   -  person Sankarann    schedule 12.02.2014


Ответы (1)


Столбцы DataGrid не являются частью визуального/логического дерева, поэтому они не получают наследования DataContext. Если вы отлаживаете программу, вы увидите ошибку в окне вывода:

Ошибка System.Windows.Data: 2: не удается найти управляющий элемент FrameworkElement или FrameworkContentElement для целевого элемента.

Здесь есть несколько вариантов.

  • Используйте это решение: http://blogs.msdn.com/b/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its-columns.aspx
  • Ссылка на некоторый элемент управления, который имеет соответствующий контекст данных. Проще всего использовать корневой контейнер (например, пользовательский элемент управления).

    Сначала инициализируйте ресурс с именем «Это» в коде (должен быть вызван до InitializeComponent):

    public MyUserControl()
    {
        Resources["This"] = this;
        InitializeComponent();
    }
    

    Затем сослаться на него в XAML:

    <DataGridTextColumn Visibility="{Binding Source={StaticResource This},
                        Path=DataContext.ShowAdditionalColumns,
                        Converter={StaticResource gridVisibilityConverter}}" />
    

(Кроме того, привязка, которую вы предоставляете для данных столбца, работает, потому что она копируется в строку в сетке, где контекст данных задается DataGrid для элемента данных.)

person Eli Arbel    schedule 12.02.2014