0
I am creating a project in Xamarin.Forms
who implements a side menu (Master/Detail
). So far I managed to display the menu correctly and list some items in it, the idea is to click on one of these menu items open another page and here is where this my problem.
How I’m using model MVVM
, mine View
is making Binding with a ViewModel
, when I select one of the menu items generates a exception
I can’t seem to solve.
I’ll show you the code to make it clearer:
View:
<StackLayout>
<ListView x:Name="listaEmpresas"
ItemsSource="{Binding ListaMenu}"
SelectedItem="{Binding ItemSelecionado}">
<ListView.Header>
<StackLayout BackgroundColor="Gray"
WidthRequest="100"
HeightRequest="40">
<Label Text="Menu de Navegação"
TextColor="White" FontSize="18"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center"/>
</StackLayout>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout>
<Label Text="{Binding Nome}"
FontSize="15"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"/>
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
Code Behind:
public partial class MasterView : ContentPage
{
public MasterViewModel ViewModel { get; set; }
public MasterView (ItensMenu menu)
{
InitializeComponent ();
this.ViewModel = new MasterViewModel();
this.BindingContext = this.ViewModel;
}
protected async override void OnAppearing()
{
base.OnAppearing();
MessagingCenter.Subscribe<ItensMenu>(this, "ItemSelecionadoMenu",
(msg) =>
{
Navigation.PushAsync(new VeiculoView());
App.MasterDetail.Detail.Navigation.PushAsync(new VeiculoView());
});
}
Viewmodel:
public class MasterViewModel : BaseViewModel
{
public string teste { set; get; }
public List<ItensMenu> ListaMenu { get; set; }
public MasterViewModel()
{
this.teste = "Teste";
this.ListaMenu = new List<ItensMenu>
{
new ItensMenu {Nome = "Creditos", Id = "1" },
new ItensMenu {Nome = "Editar Perfil", Id = "2"},
new ItensMenu {Nome = "Veiculos", Id = "3"},
new ItensMenu {Nome = "Historico", Id = "4"},
new ItensMenu {Nome = "Alertas", Id = "5"}
};
}
private ItensMenu itemSelecionado;
//Pegar o valor do item Selcionado do Menu
public ItensMenu ItemSelecionado
{
get
{
return itemSelecionado;
}
set
{
itemSelecionado = value;
if (value != null)
{
MessagingCenter.Send<ItensMenu>(itemSelecionado, "ItemSelecionadoMenu");
}
}
}
}
When I click on one of the items the following Exception occurs:
Unhandled Exception:
System.Reflection.Targetinvocationexception: Exception has been thrown by the target of an Invocation. occurred
One detail is that when I change the code Navigation.Async
by a DisplayAlert
in Codebehind it works normal.
I’m not sure, but I believe that if you put one
try/catch
in the code block that is inside the anonymous delegate being passed onMessagingCenter
can help. I believe I should be avenging a thread access vialation. Have you tried writing thePushAsync
within a blockDevice.BeginInvokeOnMainThread
? I also noticed that you are pushing twice... is that right? It was intentional?– Diego Rafael Souza
Hello Diego, I forgot to edit, the Pushasync is only once, I left there another method I was trying. I’ll try the way you indicated and come back with the answer. Thank you.
– Q.Wesley
@Diegorafaelsouza, I put the Try/catch block inside the delegate and the problem is there, but I can’t verify what it is. Could you give me an example of how to use the Device block.Begininvokeonmainthread? I tried to find out how it does, but I did not succeed.
– Q.Wesley
Clear-cut. See this example on dotnetfiddle. Usually you need to put this guy when Oce is doing an intervention on the UI thread from a background thread. Since your method is asymptomatic, and you have this anonymous delegate, that may be the case. If it is not, please edit your question including more details of the error you are experiencing from what you find on
catch
you added to the test method.– Diego Rafael Souza