Xamarin Forms中FlyoutPage菜单项Title绑定报错XFC0009如何解决?
错误原因
- 你自定义的
FlyoutPageItem类的Title是普通CLR属性,没有实现为可绑定属性(BindableProperty),XAML编译器不支持对普通属性直接使用{Binding}语法赋值,因此抛出类型不匹配/属性不存在的错误。 - 直接在
<x:Array>中声明的元素默认不在页面的视觉树范围内,无法自动继承页面的BindingContext,即使属性支持绑定也会找不到绑定源。
解决方案
方案一(更推荐):将菜单项集合放到ViewModel中构造
避免在XAML数组中写绑定,直接在ViewModel中初始化菜单列表,适配绝大多数场景,也方便后续动态修改菜单。
步骤1:确认FlyoutPageItem类实现
如果不需要动态更新菜单标题,直接使用普通CLR属性即可:
public class FlyoutPageItem { public string Title { get; set; } public ImageSource IconSource { get; set; } public Type TargetType { get; set; } }
步骤2:ViewModel中构造菜单集合
public class FlyoutPageViewModel : INotifyPropertyChanged { // 菜单集合 public ObservableCollection<FlyoutPageItem> MenuItems { get; } // 你的多语言/动态文本属性 public string NewContacts { get; set; } public string NewTodo { get; set; } public string NewReminder { get; set; } public FlyoutPageViewModel() { // 初始化时直接用属性值给Title赋值 MenuItems = new ObservableCollection<FlyoutPageItem> { new FlyoutPageItem { Title = NewContacts, IconSource = "contacts.png", TargetType = typeof(ContactsPage) }, new FlyoutPageItem { Title = NewTodo, IconSource = "todo.png", TargetType = typeof(TodoListPage) }, new FlyoutPageItem { Title = NewReminder, IconSource = "reminders.png", TargetType = typeof(ReminderPage) } }; } // INotifyPropertyChanged实现略 }
步骤3:XAML中绑定菜单集合
直接给Flyout的列表控件绑定MenuItems即可:
<FlyoutPage.Flyout> <ContentPage Title="菜单"> <ListView ItemsSource="{Binding MenuItems}" ItemTemplate="{StaticResource YourFlyoutItemTemplate}"/> </ContentPage> </FlyoutPage.Flyout>
方案二:保留XAML数组写法,改造属性与绑定
如果一定要在XAML中声明菜单项,按以下步骤修改:
步骤1:将FlyoutPageItem改为可绑定对象
public class FlyoutPageItem : BindableObject { // 把Title改造为可绑定属性 public static readonly BindableProperty TitleProperty = BindableProperty.Create(nameof(Title), typeof(string), typeof(FlyoutPageItem), string.Empty); public string Title { get => (string)GetValue(TitleProperty); set => SetValue(TitleProperty, value); } // 其他属性如果需要绑定也按同逻辑改造为可绑定属性 public ImageSource IconSource { get; set; } public Type TargetType { get; set; } }
步骤2:修改XAML绑定,指定绑定源
给你的FlyoutPage添加x:Name="RootPage",然后绑定中明确指定源为RootPage的BindingContext:
<x:Array Type="{x:Type local:FlyoutPageItem}"> <local:FlyoutPageItem Title="{Binding BindingContext.NewContacts, Source={x:Reference RootPage}}" IconSource="contacts.png" TargetType="{x:Type local:ContactsPage}" /> <local:FlyoutPageItem Title="{Binding BindingContext.NewTodo, Source={x:Reference RootPage}}" IconSource="todo.png" TargetType="{x:Type local:TodoListPage}" /> <local:FlyoutPageItem Title="{Binding BindingContext.NewReminder, Source={x:Reference RootPage}}" IconSource="reminders.png" TargetType="{x:Type local:ReminderPage}" /> </x:Array>
内容的提问来源于stack exchange,提问作者Carlos Silva
相关产品推荐
相关产品推荐

