Привязка к Windows::UI::Xaml::GridLength в C++/CX

Я пытаюсь выполнить привязку к экземпляру GridLength в приложении Магазина Windows (скомпилированном с помощью компилятора Visual Studio 2013) в C++/CX, но по какой-то причине я продолжаю получать следующую ошибку во время выполнения:

Error: Converter failed to convert value of type 'Windows.Foundation.IReference`1<Windows.UI.Xaml.GridLength>' to type 'GridLength'; BindingExpression: Path='MyHeight' DataItem='MyNamespace.MyObject'; target element is 'Windows.UI.Xaml.Controls.RowDefinition' (Name='null'); target property is 'Height' (type 'GridLength').

Мой код выглядит примерно так:

namespace MyNamespace
{
    [Windows::UI::Xaml::Data::Bindable]
    public ref class MyObject sealed
    {
        property Windows::UI::Xaml::GridLength MyHeight
        {
            Windows::UI::Xaml::GridLength get() { return myHeight; }
        }
    }
}

и мой файл XAML по существу выглядит так:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="{Binding MyHeight}"/>
    </Grid.RowDefinitions>
</Grid>

Просто к вашему сведению, другие свойства в моем классе привязываются правильно. Проблема возникает только со структурой значений GridLength. Очевидно, что свойство находит правильно, но по какой-то причине не может сопоставить типы.


person Duncan    schedule 05.07.2013    source источник


Ответы (2)


RowDefinition не является FrameworkElement, поэтому у него нет DataContext. Связывание здесь не сработает. Однако вы можете поместить Rectangle в эту строку, установить для высоты строки значение Auto и привязать Rectangle.Height к нужному свойству. Это может работать для некоторых сценариев. Для других могут быть лучшие решения, но вам нужно будет указать, чего именно вы пытаетесь достичь.

person Filip Skakun    schedule 08.07.2013
comment
Это очень разочаровывает. Существует даже сообщение о SO, предлагающее что это должно быть возможно. Ваша идея с прямоугольником кажется слишком утомительной, так как мне нужно разделить пространство n TextBlocks между n строками, только некоторые из них не видны, и, следовательно, некоторые переносятся. С вашим предложением мне пришлось бы активно слушать общую высоту (что уже ломает шаблон MVVM), делить и т. д. - person Duncan; 08.07.2013
comment
Этот ответ предназначен для WPF, и, как справедливо предполагает комментарий, неправильно помещать GridLength в модель представления. Возможно, лучше использовать StackPanel или UniformGrid. элемент управления макетом в вашем случае или какая-либо другая панель, настраиваемый элемент управления или прикрепленное свойство для управления макетом. Помните, что использование MVVM не означает, что у вас не может быть пользовательских элементов управления с кодом позади, свойствами зависимостей и т. д. - person Filip Skakun; 08.07.2013
comment
А, понятно. Спасибо. Я не планировал оставлять GridLength в своей модели представления. Вместо этого я (в конце концов) собирался сделать его целым числом, а затем предоставить конвертер для привязки. Хотя похоже, что эта идея безнадежна.. - person Duncan; 09.07.2013
comment
Простой способ получить то, что вы хотите, может состоять в том, чтобы просто добавить присоединенное свойство к вашей сетке, которое привязывается к int и автоматически обновляет RowDefinitions сетки. На самом деле я уже писал в блоге об одном таком решении для WPF, и оно должно работать так же хорошо и для WinRT. Проверьте этот пост. - person Filip Skakun; 09.07.2013
comment
Спасибо за предложение. В итоге я прислушался к изменению DataContext, а затем установил визуальное состояние (что оказалось для меня замечательным решением). Оттуда было тривиально правильно установить нужные мне свойства (кстати, в итоге я изменил RowSpan вместо RowDefinitions, так как это было более или менее то поведение, которое я в конечном итоге хотел - person Duncan; 11.07.2013

Итак, похоже, что проекция типа свойства работает не так, как вы или я ожидали бы. Он заключает свойство GridLength в IReference<T> (или, в C#, Nullable<T>). Попробуйте привязать к MyHeight.Value.

person Nate Diamond    schedule 05.07.2013
comment
Хм. Интересно, что теперь я получаю эту ошибку с этой модификацией: Error: BindingExpression path error: 'Value' property not found on 'Windows.Foundation.IReference`1<Windows.UI.Xaml.GridLength>'. - person Duncan; 06.07.2013
comment
Ах! Я нашел кое-что интересное. На основе этого, c++ и C# structs нуждаются в некоторых вспомогательных классах для взаимодействия. Ознакомьтесь с классом GridLengthHelper здесь. Если это сработает, я отредактирую ответ, чтобы отразить это. - person Nate Diamond; 06.07.2013
comment
Интересно, но я не уверен, что это проблема здесь. Петцольд упоминает, что существуют проблемы с привязкой к значениям, которые не являются свойствами, что было бы проблемой, если бы я пытался выполнить привязку к члену структуры GridLength. Но, поскольку MyHeight является свойством, я не думаю, что это применимо. Даже если бы это было так, я бы получил ошибку где-то в строке «не могу найти свойство», а не ошибку преобразования. Кроме того, я могу правильно привязываться к другим структурам значений (таким как FontWeight) - person Duncan; 06.07.2013