c# - 在最简单的 Xamarin 数据绑定(bind)期间出现 "Can not find the object referenced by"错误

标签 c# xaml xamarin mvvm xamarin.forms

我对 Xamarin 开发有些陌生。尝试完成一个相当简单的任务:在 XAML 中,将菜单页面数据绑定(bind)到注入(inject)到我的菜单页面中的 ViewModel。

这就是我的 XAML 的样子。 Intellisense 识别 _viewModel 并在 ListView 中进一步显示其属性

<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.openxlformats.org/markup-compatibility/2006"
            mc:Ignorable="d"
            BindingContext="{x:Reference_viewModel}"
            x:Class="SFC.Cliente.Mobile.Views.MenuPage"
            x:Name="Menu"
            Title="Menu">
  <StackLayout VerticalOptions="FillAndExpand">
     <ListView x:Name="ListViewMenu" HasUnevenRows="True" ItemsSource="{Binding MenuItems}">
        <ListView.ItemTemplate>
           <DataTemplate>
              <ViewCell>
                 <Grid Padding="10">
                    <Label Text="{Binding Title}" FontSize="20"/>
                 </Grid>
              </ViewCell>
           </DataTemplate>
        </ListView.ItemTemplate>
     </ListView>
  </StackLayout>
</ContentPage>

这是我的代码背后的样子。 ViewModel 被毫无问题地注入(inject)到页面的代码隐藏中,并且不为空

namespace SFC.Client.Mobile.Views
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(visible:false)]
    public partial class MenuPage : ContentPage
    {
        // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
        private readonly MenuItemsViewModel _viewModel;

        public MenuPage(MenuItemsViewModel viewModel)
        {
            _viewModel = viewModel;

            InitializeComponent();

            ListViewMenu.ItemSelected += async (sender, e) =>
            {
                if (e.SelectedItem == null)
                    return;

                var id = ((HomeMenuItem) e.SelectedItem).Id;
                var rootPage = (MainPage) Application.Current.MainPage;
                await rootPage.NavigateFromMenu(id);
            };
        }
    }
}

这是我在 InitializeComponent() 期间遇到的异常。我想通过 XAML 连接数据绑定(bind),而不是通过代码。我试过将 _viewModel 设为公共(public)或私有(private)、属性(property)或成员:没有变化。我做错了什么?

{System.Collections.ListDictionaryInternal}
-2146233088
(null)
(null)
"Position 7:14. Can not find the object referenced by _viewModel"
"Xamarin.Forms.Xaml"
" at Xamarin.Forms.Xaml.Reference.ProvideValue(System.IServiceProvider serviceProvider) [0..."
{System.Reflection.MonoMethod}

最佳答案

我必须同意上面 Ivan Ičin 的观点。

我不确定为什么在 XAML 上设置绑定(bind)上下文如此重要,而您可以轻松地做到这一点:

public partial class MenuPage : ContentPage
{
    // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
    // private readonly MenuItemsViewModel _viewModel;

    public MenuPage(MenuItemsViewModel viewModel)
    {
        BindingContext = viewModel; // <---------- changed line

        ...
    }
}

更新:找到了可能的解决方案。

在您的页面上设置静态属性,例如:

public static MenuItemsViewModel BindingContextInstance { get; set; } = null;

在调用 InitializeComponent() 之前,将您的 View 模型分配给上述静态成员:

public MenuPage(MenuItemsViewModel viewModel)
{
    BindingContextInstance = viewModel;
    InitializeComponent();
      ...
} 

然后在 XAML 中,添加一个新的 xmlns 条目并设置 BindingContext:

xmlns:views="clr-namespace:SFC.Client.Mobile.Views"
BindingContext="{x:Static views:MenuPage.BindingContextInstance}"

Note: This does not work for auto complete in the current stable version of Visual Studio for Mac (8.1.5.9), but does work in the current Preview version (8.2) and in the current version of Visual Studio 2019 (16.1.6) on Windows. Set your update channel to Preview in Visual Studio for Mac in the Visual Studio Update dialog and when the updates are downloaded, Restart and Install updates.

关于c# - 在最简单的 Xamarin 数据绑定(bind)期间出现 "Can not find the object referenced by"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57100698/

相关文章:

c# - 如何从 Selenium 中的 href 链接获取属性值

.net - VS Xaml 设计器错误

xaml - Xamarin 表单按钮没有边框问题

c# - 如何在代码后面设置Storyboard.SetTargetProperty?

c# - 使用存储库的工作单元模式中的依赖注入(inject)

c# - 将 ZIP 文件插入数据库

xaml - 如何在XAML中引用图标资源文件引用

c# - 隐式 'this'无法引用Xamarin中的扩展方法

c# - 如何在 Xamarin 中填充 TableView ?

xamarin - 如何从 iOS 自定义渲染器调用基本帧渲染器中的方法?