c# - Xamarin.Forms 自定义控件 BindingContext 在 DataTemplate 中不起作用?
问题描述
我正在尝试将 BindableLayout 与 StackLayout 一起使用来显示集合中的项目,但由于某种原因,绑定在使用 BindableLayout 时不起作用。在使用 XAML 热重新加载进行调试时,它有时会在重新加载后开始工作,但在刷新 UI 后不会继续工作。
如果需要, repo 在这里,但这是有问题的代码:
页面 XAML:(自定义控件为 ComicInfoView)
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pages="clr-namespace:ComicBud.Pages"
xmlns:views="clr-namespace:ComicBud.Views"
mc:Ignorable="d"
x:Class="ComicBud.Pages.HomePage"
Title="ComicBud">
<ContentPage.ToolbarItems>
<ToolbarItem IconImageSource="ic_add_white_36dp" Command="{Binding AddComicUrlCommand}" />
</ContentPage.ToolbarItems>
<ContentPage.Resources>
<x:String x:Key="pageBorder">10</x:String>
</ContentPage.Resources>
<ContentPage.Content>
<RefreshView IsRefreshing="{Binding IsRefreshing}"
Command="{Binding RefreshCommand}">
<ScrollView Orientation="Vertical">
<StackLayout Margin="0, 10, 0, 10">
<StackLayout Orientation="Vertical"
IsVisible="{Binding IsAnyComics}">
<Label Text="Using BindableLayout"
FontSize="Subtitle"
Margin="10, 0, 10, 0"/>
<ScrollView Orientation="Horizontal"
HorizontalScrollBarVisibility="Never">
<StackLayout Orientation="Horizontal"
Spacing="10"
Padding="10, 5, 10, 5"
BindableLayout.ItemsSource="{Binding Comics}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<views:ComicInfoView />
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ScrollView>
</StackLayout>
<StackLayout Orientation="Vertical"
IsVisible="{Binding IsAnyComics}">
<Label Text="Manual"
FontSize="Subtitle"
Margin="10, 0, 10, 0"/>
<ScrollView Orientation="Horizontal"
HorizontalScrollBarVisibility="Never">
<StackLayout Orientation="Horizontal"
Spacing="10"
Padding="10, 5, 10, 5">
<views:ComicInfoView />
</StackLayout>
</ScrollView>
</StackLayout>
</StackLayout>
</ScrollView>
</RefreshView>
</ContentPage.Content>
ComicInfoView.xaml:
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:ComicBud.Views"
mc:Ignorable="d"
x:Class="ComicBud.Views.ComicInfoView">
<ContentView.BindingContext>
<views:ComicInfoViewModel />
</ContentView.BindingContext>
<ContentView.Content>
<StackLayout Orientation="Horizontal">
<Frame WidthRequest="60"
HeightRequest="84"/>
<StackLayout RelativeLayout.XConstraint=
"{ConstraintExpression Type=RelativeToParent,
Property=Width,
Factor=0,
Constant=100}"
Margin="0, 5, 10, 0"
Spacing="0">
<Label Text="{Binding ComicName}"
HorizontalTextAlignment="Start"
FontSize="Subtitle"
LineBreakMode="WordWrap"
WidthRequest="100"/>
<Label Text="Last Read"
HorizontalTextAlignment="Start"
FontSize="Micro"
Margin="0, 5, 0, 0"/>
<Label Text="3 days ago"
HorizontalTextAlignment="Start"
FontSize="Small"/>
<Label Text="Updated"
HorizontalTextAlignment="Start"
FontSize="Micro"
Margin="0, 5, 0, 0"/>
<Label Text="2 days ago"
HorizontalTextAlignment="Start"
FontSize="Small"/>
</StackLayout>
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OpenComicCommand}"/>
</StackLayout.GestureRecognizers>
</StackLayout>
</ContentView.Content>
ComicInfoViewModel.cs
using System.ComponentModel;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using FreshMvvm;
using ComicBud.Pages;
using ComicBud.Systems;
namespace ComicBud.Views
{
public class ComicInfoViewModel : INotifyPropertyChanged
{
public ComicInfoViewModel()
{
OpenComicCommand = new Command(async () => await OpenComic());
}
public event PropertyChangedEventHandler PropertyChanged;
private Comic _comic;
public Comic Comic
{
get { return _comic; }
set
{
_comic = value;
OnPropertyChanged();
OnPropertyChanged(nameof(ComicName));
}
}
public string ComicName
{
get { return "Binding Is Working"; }
}
public Command OpenComicCommand { get; }
private async Task OpenComic()
{
var navService = FreshIOC.Container.Resolve<IFreshNavigationService>(Constants.DefaultNavigationServiceName);
var page = FreshPageModelResolver.ResolvePageModel<ComicDetailPageModel>();
await navService.PushPage(page, null);
}
private void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
编辑:在 DataTemplate 中用一些东西(Frame、ContentView 等)包装 ComicInfoView 似乎可以解决它。像这样:
<BindableLayout.ItemTemplate>
<DataTemplate>
<ContentView>
<views:ComicInfoView/>
</ContentView>
</DataTemplate>
</BindableLayout.ItemTemplate>
我会将问题标记为已解决,但如果有人能解释为什么会这样,将不胜感激!
解决方案
推荐阅读
- jsp - Teamcity:更改内置下拉菜单的顺序/默认值
- mule - Mule 3 HTML 作为属性值
- c++ - 执行速度方面的通用与重载
- magento2 - 如何修复magento上的文件导出异常错误?
- ios - 使用 pod install 安装 pod 后,应用程序无法启动,给我错误 add -DFIRCore_VERSION=... to the build invocation”
- java - 在 Java 指令中调用 freemarker 函数
- junit - 我如何使用 JUnit 5 解决这个 ASM 问题
- javascript - Reactjs如何分隔复选框值
- python - Django - 重定向后传递对象
- chatbot - Microsoft Teams:聊天消息中的内嵌图像链接 - 它们可以在其他聊天中重复使用吗?