Xamarin Forms:动态创建 Listview 项 -> BindingContext 问题
Xamarin Forms: Dynamically creating a Listview item -> Problem with BindingContext
正如我在 another post here on Whosebug 中描述的那样,我试图获得不同的布局(一个框架跨越多个列表视图项目)。现在我决定尝试以下方法:我的 ViewModel 是一个列表列表(就像分组列表视图一样)。但是,我没有使用分组列表视图,而是有一个普通的 ListView,其中只要 ParentViewCell 的 bindingContext 可用,就会在代码隐藏中创建子列表的单个项目:
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,而是父的CommentViewModel。我像这样检查了 ChildCommentViewCell 的 BindingContext
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);
}
并且控制台上的输出很好。然而,当 运行ning 在我的 phone 上时,实际内容(如上所述)是 ParentCommentViewModel 的内容。有什么想法吗?
ChildCommentViewCell 元素的 XAML 代码如下:
<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>
另外一件事:我尝试调试 "Appearing"-Event,但是它甚至没有被调用一次...?!
非常感谢您!
在 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);
}
}
正如我在 another post here on Whosebug 中描述的那样,我试图获得不同的布局(一个框架跨越多个列表视图项目)。现在我决定尝试以下方法:我的 ViewModel 是一个列表列表(就像分组列表视图一样)。但是,我没有使用分组列表视图,而是有一个普通的 ListView,其中只要 ParentViewCell 的 bindingContext 可用,就会在代码隐藏中创建子列表的单个项目:
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,而是父的CommentViewModel。我像这样检查了 ChildCommentViewCell 的 BindingContext
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);
}
并且控制台上的输出很好。然而,当 运行ning 在我的 phone 上时,实际内容(如上所述)是 ParentCommentViewModel 的内容。有什么想法吗?
ChildCommentViewCell 元素的 XAML 代码如下:
<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>
另外一件事:我尝试调试 "Appearing"-Event,但是它甚至没有被调用一次...?!
非常感谢您!
在 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);
}
}