【问题标题】:Navigation in Xamarin.forms: buffer nullXamarin.forms 中的导航:缓冲区空
【发布时间】:2020-11-13 17:42:17
【问题描述】:

在 Xamarin.Forms 应用程序中,我在 Page (Page_1) 上有一个按钮,该按钮将我发送到另一个 Page (Page_2) 和声明

await Navigation.PushAsync (new Page_2 ());

在这个Page 上,我有几个ImageButtons,当我点击声明时,它们都会返回到Page_1

await Navigation.PopAsync ();

这第一次有效,但第二次按下 Page_1 上的按钮时,我转到 Page_2,然后当我点击 @987654332 @应用程序退出并显示错误消息:

System.ArgumentNullException 消息 = 缓冲区不能为空。 参数名称:缓冲区

如何使Navigation.NavigationStack 仍然包含Page_1?

非常感谢您的帮助。

为 Deczaloth 添加:这是第一页的部分代码:

private async void btnModifImage_Clicked(object sender, EventArgs e)
    {
        string imgLocation;
        // affichage et choix : gallerie ou internet
        imgLocation = await DisplayActionSheet("Emplacement", "Annuler", null, imageLocation);
        if (imgLocation == "Gallerie")
        {
            // chargement image depuis gallerie
            imageChanged = true;
            article_nomcat = pickerCat.Title;
            article_unit = pickerUnit.Title;
            try
            {
                FileData fileData = await CrossFilePicker.Current.PickFile();
                //
                var filepath = fileData.FilePath;
                //
                if (fileData == null)
                    return; // user canceled file picking

                newimageByte = fileData.DataArray;
                resizedImageByte = await ImageResizer.ResizeImage(newimageByte, 100, 100);

                if (resizedImageByte != null)
                {
                    imageChanged = true;
                    var stream1 = new MemoryStream(resizedImageByte);
                    ImageArticle.Source = ImageSource.FromStream(() => stream1);
                }
            }
            catch (Exception ex)
            {
                imageChanged = false;
            }
        }
        else
        {
            App.ImageName = name.Text;
            await Navigation.PushAsync(new ImageBingPage());
        }
    }

以及第二页ImageBingPage的部分代码:

private async void img1_Clicked(object sender, EventArgs e)
    {
        byte[] img1Byte = await DownloadImageAsync(img1Path);
        App.imgByte = img3Byte;
        await Navigation.PopAsync();
    }

还有第二页的变大:

protected override void OnAppearing()
    {
        base.OnAppearing();
        SearchImage();
        base.OnDisappearing();
    }

    public void SearchImage()
    {
        
        List<Images> imageList = new List<Images>();
        SearchResult bingResult = BingImageSearch(App.ImageName);
        var res = JsonConvert.DeserializeObject<ResponseModel>(bingResult.jsonResult);
        for (int i = 0; i < res.value.Count; i++)
        {
            imageList.Add(new Images { ImagePath = res.value[i].contentUrl });
        }
        img1.Source = ImageSource.FromUri(new Uri(imageList[0].ImagePath));
        img1Path = imageList[0].ImagePath;
        img2.Source = ImageSource.FromUri(new Uri(imageList[1].ImagePath));
        img2Path = imageList[1].ImagePath;
        img3.Source = ImageSource.FromUri(new Uri(imageList[2].ImagePath));
        img3Path = imageList[2].ImagePath;
    }

    static SearchResult BingImageSearch(string searchQuery)
    {
        var uriQuery = baseURl + "?q=" + Uri.EscapeDataString(searchQuery);
        WebRequest request = HttpWebRequest.Create(uriQuery);
        request.Headers["Ocp-Apim-Subscription-Key"] = APIKey;
        HttpWebResponse response = (HttpWebResponse)request.GetResponseAsync().Result;
        string json = new StreamReader(response.GetResponseStream()).ReadToEnd();
        var searchResult = new SearchResult();
        searchResult.jsonResult = json;
        searchResult.relevantHeaders = new Dictionary<String, String>();
        foreach (String header in response.Headers)
        {
            if (header.StartsWith("BingAPIs-") || header.StartsWith("X-MSEdge-"))
                searchResult.relevantHeaders[header] = response.Headers[header];
        }
        return searchResult;
    }


    async Task<byte[]> DownloadImageAsync(string imageUrl)
    {
        try
        {
            using (var httpResponse = await _httpClient.GetAsync(imageUrl))
            {
                if (httpResponse.StatusCode == HttpStatusCode.OK)
                {
                    return await httpResponse.Content.ReadAsByteArrayAsync();
                }
                else
                {
                    //Url is Invalid
                    return null;
                }
            }
        }
        catch (Exception e)
        {
            //Handle Exception
            return null;
        }
    }

为 Deczaloth 添加 2:您是对的:堆栈不为空(请参见随附的两个屏幕截图)。那么问题出在哪里呢?

为 Jack 编辑:我已修改我的代码以简化问题:

private async void img1_Clicked(object sender, EventArgs e)
    {
        //byte[] img1Byte = await DownloadImageAsync(imgPath[0]);
        //App.imgByte = img1Byte;
        await Navigation.PopAsync();
    }

    private async void img2_Clicked(object sender, EventArgs e)
    {
        //byte[] img2Byte = await DownloadImageAsync(imgPath[1]);
        //App.imgByte = img2Byte;
        await Navigation.PopAsync();
    }

现在我可以在 ArticleEntry 页面和 ImageBingPage 页面之间进行 3 次往返,但之后,应用程序仍然崩溃。

为 Jack 编辑:ArticleEntry 页面上有代码:

protected override async void OnAppearing()
    {
        base.OnAppearing();
        if (App.AddArticle == true)
        {
            ToolbarItems.Remove(btnDelete);
        }
        
        //
        _article = (Article)BindingContext;
        old_article_ID = _article.ID;
        old_article_name = _article.Name;
        article_nomcat = _article.NomCat;
        article_unit = _article.UniteMesure;
        //
        if (_article.ID == 0)
        {
            name.Focus();
        }
        //
        if (pickerCat.Title != null & pickerCat.Title != "choisissez une catégorie")
        {
            _article.NomCat = pickerCat.Title;
            pickerCat.TitleColor = Color.Black;
        }
        else
        {
            if (_article.NomCat != null)
            {
                pickerCat.Title = _article.NomCat;
                pickerCat.SelectedItem = _article.NomCat;
                pickerCat.TitleColor = Color.Black;
            }
            else
            {
                pickerCat.Title = "choisissez une catégorie";
                pickerCat.TitleColor = Color.Gray;
            }
            
        }
        //
        if (pickerUnit.Title != null & pickerUnit.Title != "choisissez une unité de mesure")
        {
            _article.UniteMesure = pickerUnit.Title;
            pickerUnit.TitleColor = Color.Black;
        }
        else
        {
            if (_article.UniteMesure != null)
            {
                pickerUnit.Title = _article.UniteMesure;
                pickerUnit.SelectedItem = _article.UniteMesure;
                pickerUnit.TitleColor = Color.Black;
            }
            else
            {
                pickerUnit.Title = "choisissez une unité de mesure";
                pickerUnit.TitleColor = Color.Gray;
            }
        }
        //
        if (pickerListeAchats.Title != null & pickerListeAchats.Title != "choisissez une liste d'achats")
        {
            //_article.UniteMesure = pickerUnit.Title;
            pickerListeAchats.TitleColor = Color.Black;
        }
        
        //
        ReadAllCategorieList dbcategorie = new ReadAllCategorieList();
        DB_CategorieList = dbcategorie.GetAllCategorie(); //Get all DB Categorie
        // trier  
        DB_CategorieList_Sorted = DB_CategorieList.OrderBy(i => i.NomCat).ToList();
        //
        // rempliir la liste du picker Cat
        string[] pickerListCat;
        List<string> pkListCat = new List<string>();
        foreach (var item in DB_CategorieList_Sorted)
        {
            string element = item.NomCat;
            //pickerCat.Items.Add(element);
            pkListCat.Add(element);
        }
        pickerListCat = pkListCat.ToArray();
        pickerCat.ItemsSource = pickerListCat;
        //
        // rempliir la liste du picker Unit
        ReadAllUnitList dbunit = new ReadAllUnitList();
        DB_UnitList = dbunit.GetAllUnit();
        // trier  
        DB_UnitList_Sorted = DB_UnitList.OrderBy(i => i.UniteMesure).ToList();
        //
        List<string> pickerListUnit = new List<string>();
        foreach (var item in DB_UnitList_Sorted)
        {
            string element = item.UniteMesure;
            pickerListUnit.Add(element);
        }
        pickerUnit.ItemsSource = pickerListUnit;
        //
        // remplir la liste du picker ListeAchats
        ReadAllListeAchatsList dblisteachats = new ReadAllListeAchatsList();
        DB_ListeAchatsList = dblisteachats.GetAllListeAchats();
        // trier  
        DB_ListeAchatsList_Sorted = DB_ListeAchatsList.OrderBy(i => i.NomListe).ToList();
        //
        List<string> pickerListAchat = new List<string>();
        foreach (var item in DB_ListeAchatsList_Sorted)
        {
            string element = item.NomListe;
            pickerListAchat.Add(element);
        }
        pickerListeAchats.ItemsSource = pickerListAchat;
        //
        //
        imageByte = _article.ImageArt;
        //
        // convertir le byte[] en bitmapimage (si != 0)
        if (_article.ImageArt != null)
        {
            if (imageChanged)
            {
                var stream1 = new MemoryStream(newimageByte);
                ImageArticle.Source = ImageSource.FromStream(() => stream1);
            }
            else
            {
                var stream1 = new MemoryStream(imageByte);
                ImageArticle.Source = ImageSource.FromStream(() => stream1);
            }
        }
        else
        {
            if (imageChanged == false)
            {
                imageByte = ImageDataFromResource("MemoCourses.Assets.Images.appareil_photo.png");
                var stream1 = new MemoryStream(imageByte);
                ImageArticle.Source = ImageSource.FromStream(() => stream1);
            }
        }
        //
        if (App.imgByte != null)
        {
            resizedImageByte = await ImageResizer.ResizeImage(App.imgByte, 100, 100);
            if (resizedImageByte != null)
            {
                imageChanged = true;
                var stream1 = new MemoryStream(resizedImageByte);
                ImageArticle.Source = ImageSource.FromStream(() => stream1);
            }
        }
        //
        base.OnDisappearing();
        App.AddArticle = false;
    }

根据 Jack 的 cmets 更改代码

protected override async void OnAppearing()
    {
        base.OnAppearing();
        if (App.AddArticle == true)
        {
            ToolbarItems.Remove(btnDelete);
        }
        //
        _article = (Article)BindingContext;
        old_article_ID = _article.ID;
        old_article_name = _article.Name;
        article_nomcat = _article.NomCat;
        article_unit = _article.UniteMesure;
        //
        if (_article.ID == 0)
        {
            name.Focus();
        }
        //
        if (pickerCat.Title != null & pickerCat.Title != "choisissez une catégorie")
        {
            _article.NomCat = pickerCat.Title;
            pickerCat.TitleColor = Color.Black;
        }
        else
        {
            if (_article.NomCat != null)
            {
                pickerCat.Title = _article.NomCat;
                pickerCat.SelectedItem = _article.NomCat;
                pickerCat.TitleColor = Color.Black;
            }
            else
            {
                pickerCat.Title = "choisissez une catégorie";
                pickerCat.TitleColor = Color.Gray;
            }
            
        }
        //
        if (pickerUnit.Title != null & pickerUnit.Title != "choisissez une unité de mesure")
        {
            _article.UniteMesure = pickerUnit.Title;
            pickerUnit.TitleColor = Color.Black;
        }
        else
        {
            if (_article.UniteMesure != null)
            {
                pickerUnit.Title = _article.UniteMesure;
                pickerUnit.SelectedItem = _article.UniteMesure;
                pickerUnit.TitleColor = Color.Black;
            }
            else
            {
                pickerUnit.Title = "choisissez une unité de mesure";
                pickerUnit.TitleColor = Color.Gray;
            }
        }
        //
        if (pickerListeAchats.Title != null & pickerListeAchats.Title != "choisissez une liste d'achats")
        {
            pickerListeAchats.TitleColor = Color.Black;
        }
        
        //
        ReadAllCategorieList dbcategorie = new ReadAllCategorieList();
        DB_CategorieList = dbcategorie.GetAllCategorie(); //Get all DB Categorie
        // trier  
        DB_CategorieList_Sorted = DB_CategorieList.OrderBy(i => i.NomCat).ToList();
        //
        // rempliir la liste du picker Cat
        string[] pickerListCat;
        List<string> pkListCat = new List<string>();
        foreach (var item in DB_CategorieList_Sorted)
        {
            string element = item.NomCat;
            pkListCat.Add(element);
        }
        pickerListCat = pkListCat.ToArray();
        pickerCat.ItemsSource = pickerListCat;
        //
        // rempliir la liste du picker Unit
        ReadAllUnitList dbunit = new ReadAllUnitList();
        DB_UnitList = dbunit.GetAllUnit();
        // trier  
        DB_UnitList_Sorted = DB_UnitList.OrderBy(i => i.UniteMesure).ToList();
        //
        List<string> pickerListUnit = new List<string>();
        foreach (var item in DB_UnitList_Sorted)
        {
            string element = item.UniteMesure;
            pickerListUnit.Add(element);
        }
        pickerUnit.ItemsSource = pickerListUnit;
        //
        // remplir la liste du picker ListeAchats
        ReadAllListeAchatsList dblisteachats = new ReadAllListeAchatsList();
        DB_ListeAchatsList = dblisteachats.GetAllListeAchats();
        // trier  
        DB_ListeAchatsList_Sorted = DB_ListeAchatsList.OrderBy(i => i.NomListe).ToList();
        //
        List<string> pickerListAchat = new List<string>();
        foreach (var item in DB_ListeAchatsList_Sorted)
        {
            string element = item.NomListe;
            pickerListAchat.Add(element);
        }
        pickerListeAchats.ItemsSource = pickerListAchat;
        //
        //
        imageByte = _article.ImageArt;
        //
        // convertir le byte[] en bitmapimage (si != 0)
        if (_article.ImageArt != null)
        {
            if (imageGallery)
            {
                var stream1 = new MemoryStream(resizedImageByte);
                ImageArticle.Source = ImageSource.FromStream(() => stream1);
            }
            else
            {
                if (App.imgByte == null)
                {
                    // image depuis la base SQLite
                    var stream1 = new MemoryStream(imageByte);
                    ImageArticle.Source = ImageSource.FromStream(() => stream1);
                }
                else
                {
                    // image depuis internet
                    var stream1 = new MemoryStream(App.imgByte);
                    ImageArticle.Source = ImageSource.FromStream(() => stream1);
                }
            }
        }
        else
        {
            if (imageChanged == false)
            {
                // image par défaut
                imageByte = ImageDataFromResource("MemoCourses.Assets.Images.appareil_photo.png");
                var stream1 = new MemoryStream(imageByte);
                ImageArticle.Source = ImageSource.FromStream(() => stream1);
            }
        }
        //
        if (App.imgByte != null & imageInternet == true)
        {
            resizedImageByte = await ImageResizer.ResizeImage(App.imgByte, 100, 100);
            if (resizedImageByte != null)
            {
                var stream1 = new MemoryStream(resizedImageByte);
                ImageArticle.Source = ImageSource.FromStream(() => stream1);
            }
        }
        //
        base.OnDisappearing();
        App.AddArticle = false;
        imageGallery = false;
        imageInternet = false;
    }

【问题讨论】:

  • 这个异常看起来不像是说 NavigationStack 有问题。问题应该出在其他地方。你能分享更多细节吗?我创建了一个简单的解决方案,只执行您描述的操作(从一页到另一页并返回),但我没有遇到任何异常......
  • 我添加了几行代码以更好地了解错误是如何发生的。让我想起导航问题的是,如果我在添加图像后离开 ArticleEntry 页面,然后返回该页面并再次更改图像,我就没有这个错误。感谢您的帮助。
  • 你能贴出异常的stacktrace吗?
  • 我正在向您发送一个链接 1drv.ms/t/s!Am0yZGVkguZvjqV5tP0gCFIdg1JUxQ?e=uwokAb 以打开堆栈跟踪 - 希望这就是您要问我的。如果没有,请告诉我如何获得它。非常感谢。

标签: xamarin.forms navigation


【解决方案1】:

问题不是由NavigationStack引起的。

1.你不应该在OnAppearing中调用base.OnDisappearing();:

protected override void OnAppearing()
{
    base.OnAppearing();
    SearchImage();
    //remove this line
    //base.OnDisappearing();
}

2.你得到一个java.io.IOException: Cleartext HTTP traffic to aardbeienzo.com not permitted,你没有权限加载以http开头的url:

进入Android项目-->属性-->Assemblyinfo.cs,添加UsesCleartextTraffic = true:

// Add some common permissions, these can be removed if not needed
[assembly: UsesPermission(Android.Manifest.Permission.Internet)]
[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]

[assembly: Application(UsesCleartextTraffic = true)]

更新:

private async void img1_Clicked(object sender, EventArgs e)
    {
        byte[] img1Byte = await DownloadImageAsync(img1Path);
        //App.imgByte = img3Byte;
        App.imgByte = img1Byte;
        await Navigation.PopAsync();
    }

更新 2:

一般来说,如果你正确使用Navigation push/pop,是不会报错的。注意Page的OnAppearing方法,查看那里的代码。

Marcel Delhaye 已在问题中更新了正确的代码。

【讨论】:

  • 您好 Jack,我应用了您的更改,并且解决了两个问题之一:所有法师现在都可以正确显示。但是,当我通过单击带有以下指令的图像按钮返回 ArticleEntry 页面时,应用程序仍然崩溃:await Navigation.PopAsync ();这是查看堆栈跟踪的链接:[链接]1drv.ms/t/s!Am0yZGVkguZvjqV6FDE9mD2mQ3btpA?e=toFT7r非常感谢您的帮助。
  • PS:这是第一次返回后的堆栈跟踪:在这种情况下,应用程序不会崩溃[链接]1drv.ms/t/s!Am0yZGVkguZvjqV7bL_jQfv1uhrW_Q?e=msF0P3
  • 另一个附加信息:当我第二次单击 ArticleEntry 页面中的编辑图像按钮时,然后在 ImageBingPage 页面上,我单击后退箭头而不是单击图像按钮,我有相同的结果:应用程序崩溃。
  • 您的堆栈跟踪中还有另一个异常:System.InvalidCastException: Impossible d'effectuer un cast d'un objet de type 'Mono.Debugger.Soft.PointerValue' en type 'Mono.Debugger.Soft.PrimitiveValue'.
  • Page1的OnAppearing方法有代码吗?这不是导航造成的,可能是返回时在 OnAppearing 方法中加载了一些东西造成的。
猜你喜欢
  • 2018-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-14
  • 2016-12-03
  • 1970-01-01
  • 2012-05-27
  • 1970-01-01
相关资源
最近更新 更多