Xamarin Forms: динамическое создание элемента Listview - ›Проблема с BindingContext

как я уже описывал в другом сообщении здесь, в Stackoverflow, я был пытается получить другой макет (один фрейм, охватывающий несколько элементов списка). Теперь я решил попробовать следующий подход: Моя ViewModel - это список списков (как и для сгруппированного списка). Однако вместо использования сгруппированного списка у меня есть обычный ListView, в котором отдельные элементы дочернего списка будут созданы в коде программной части, как только станет доступен 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>

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

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


person Wolffi82    schedule 03.10.2018    source источник


Ответы (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);
                }
}
person Wolffi82    schedule 03.10.2018