Формы Xamarin: динамическое создание элемента списка -> проблема с BindingContext

Как я уже описывал в другом посте здесь, на Stackru, я пытался получить другой макет (один кадр, охватывающий несколько элементов списка). Теперь я решил попробовать следующий подход: Моя ViewModel представляет собой список списков (так же, как для группового списка). Однако вместо того, чтобы использовать сгруппированный просмотр списка, у меня есть обычный ListView, в котором отдельные элементы дочернего списка будут создаваться в Code-behind, как только bindingContext из ParentViewCell станет доступным:

private void CommentViewCell_BindingContextChanged(object sender, EventArgs e)
        {
            if (this.BindingContext == null) return;
            var model = this.BindingContext as CommentViewModel;


            DateCommentViewCell dateCell = new DateCommentViewCell
            {
                BindingContext = model
            };

            ParentCommentViewCell parentCell = new ParentCommentViewCell
            {
                BindingContext = model
            };

            ContentStackView.Children.Add(dateCell.View);
            ContentStackView.Children.Add(parentCell.View);

            foreach (CommentBaseViewModel cbvm in model)
            {
                if (cbvm is CommentViewModel)
                {
                    ChildCommentViewCell childCell = new ChildCommentViewCell
                    {
                        BindingContext = cbvm
                    };

                    ContentStackView.Children.Add(childCell.View);
                }
            }
        }

Когда я запускаю это, визуальные эффекты на самом деле в порядке и выглядят так, как я их задумал.

Однако BindingContext неверен: ChildCommentViewCell BindingContext ссылается не на CommentViewModel дочернего элемента, а на родительский при отображении. Я проверил BindingContext ChildCommentViewCell, как это

public ChildCommentViewCell ()
        {
            InitializeComponent ();
            BindingContextChanged += ChildCommentViewCell_BindingContextChanged;

        }

        private void ChildCommentViewCell_BindingContextChanged(object sender, EventArgs e)
        {
            Debug.WriteLine("### ChildCommentViewCell BindingContext Changed");
            test();            
        }

        public void test()
        {
            var context = this.BindingContext as CommentViewModel;
            Debug.WriteLine("### Instance: " + this.GetHashCode());
            Debug.WriteLine("### \tBinding Context: " + context.CommentModel.Text);
            Debug.WriteLine("### \tLabel: " + ChildCommentText.Text);
        }

и вывод на консоль просто отлично. Однако при работе на моем телефоне фактический контент (как написано выше) соответствует ParentCommentViewModel. Есть идеи?

Код XAML элемента ChildCommentViewCell является следующим:

<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="App.View.ViewCell.ChildCommentViewCell">
    <StackLayout Padding="10,0" Orientation="Horizontal" HorizontalOptions="FillAndExpand">
        <StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
            <StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand">
                <StackLayout Grid.Column="0" VerticalOptions="FillAndExpand" Orientation="Vertical" Spacing="0">
                    <Label Text="{Binding CommentModel.AuthorName}" Style="{StaticResource CommentAuthor}"/>
                </StackLayout>
                <Frame IsClippedToBounds="True" HasShadow="False" Margin="5" Padding="3" BackgroundColor="LightGray" CornerRadius="3.0">
                    <StackLayout Grid.Column="1" VerticalOptions="FillAndExpand" Orientation="Vertical" Spacing="0">
                        <Label x:Name="ChildCommentText" Text="{Binding Path=CommentModel.Text, StringFormat=' {0}'}" Style="{StaticResource CommentContent}"/>
                        <Label Text="{Binding CommentTimeAgo}" Style="{StaticResource CommentTime}" HorizontalOptions="Start"/>
                    </StackLayout>
                </Frame>
            </StackLayout>
        </StackLayout>
    </StackLayout>
</ViewCell>

Еще одна вещь: я попытался отладить "Появление"- событие, однако это даже не вызывается один раз...?!

Заранее большое спасибо!

1 ответ

Решение

Нашел мою проблему в методе BindingContextChanged: мне пришлось явно связать BindingContext с представлением, а не только с ViewCell:

foreach (CommentBaseViewModel cbvm in model)
            {
                if (cbvm is CommentViewModel)
                {
                    ChildCommentViewCell childCell = new ChildCommentViewCell
                    {
                        BindingContext = cbvm
                    };
                    childCell.View.BindingContext = cbvm;
                    ContentStackView.Children.Add(childCell.View);
                }
}
Другие вопросы по тегам