Command Binding not working on an ImageCell

rarenivarrarenivar USMember ✭✭
edited September 2015 in Xamarin.Forms

I can't seem to get the Command interface to work with an ImageCell in XAML.
The rest of the data that I'm binding the view with is working just fine, with the exception of the Command property, which is not getting called.

I know I must missing something or perhaps my syntax is wrong.

Here's a portion of my XAML file....

<ListView x:Name="MenuItemsList" ItemsSource="{Binding Data}"> <ListView.ItemTemplate> <DataTemplate> <ImageCell Text="{Binding Title}" TextColor="Black" ImageSource="{Binding IconSource}"> <ImageCell.GestureRecognizer> <TapGestureRecognizer Command="{Binding MenuItemPressed}"> </TapGestureRecognizer> </ImageCell.GestureRecognizer> </ImageCell> </DataTemplate> </ListView.ItemTemplate> </ListView>

I also tried adding the Command attribute directly in the ImageCell like so...

<ListView x:Name="MenuItemsList" ItemsSource="{Binding Data}"> <ListView.ItemTemplate> <DataTemplate> <ImageCell Text="{Binding Title}" TextColor="Black" ImageSource="{Binding IconSource}" Command="{Binding MenuItemPressed}"> </ImageCell> </DataTemplate> </ListView.ItemTemplate> </ListView>

And here's my view model...

class MainMenuViewModel: ViewModelBase { public List<MainMenuItem> Data { get; set; } public MainMenuViewModel() { Data = new MenuListData(); MenuItemPressed = new Command(NavigateToPage); } void NavigateToPage() { System.Diagnostics.Debug.WriteLine("executing the navigatetopage command"); } public ICommand MenuItemPressed { private set; get; } }

Thanks.

Posts

  • stvansolanostvansolano UMInsider, University ✭✭✭

    Hey @RamiroM since your ItemsSource are MainMenuItem objects you should define the 'MenuItemPressed' inside the MainMenuItem class so it can get the correct binding context level.

    Hope it helps

  • rarenivarrarenivar USMember ✭✭

    @EstebanSolano - You're right, the reason why it wasn't working is because I was inside the "Data" object context when trying to bind the Command to the ImageCell. Since I'm trying to follow the MVVM design pattern, I would prefer not to add the "MenuItemPressed" logic to my MainMenuItem class(my model). Is there another way have two item sources for the listview?

    Thanks.

  • rarenivarrarenivar USMember ✭✭

    For anybody having the same problem, I solved this by setting the Command binding source to my ViewModel instance, then specifying the path to the Command (which is a part of the ViewModel). Here's the XAML...

    <ImageCell Text="{Binding Title}" TextColor="Black" ImageSource="{Binding IconSource}" Command="{Binding Source={StaticResource mainMenuViewModel}, Path=MenuItemPressed}" CommandParameter="{Binding Title}"> </ImageCell>

  • KieranPierceKieranPierce GBMember

    can you show me the code for the view model, i am getting an error with the static resource part and dont really understand why

  • rarenivarrarenivar USMember ✭✭

    @KieranPierce - The ViewModel is the same as in my original post, here it is...
    class MainMenuViewModel: ViewModelBase { public List<MainMenuItem> Data { get; set; } public MainMenuViewModel() { Data = new MenuListData(); MenuItemPressed = new Command(NavigateToPage); } void NavigateToPage() { System.Diagnostics.Debug.WriteLine("executing the navigatetopage command"); } public ICommand MenuItemPressed { private set; get; } }

    Hope that helps.

  • KieranPierceKieranPierce GBMember

    cool thanks, still don't quite get it, how is the static-resource created?

  • rarenivarrarenivar USMember ✭✭

    I create the ViewModel object in the XAML file...
    <ContentPage.Resources> <ResourceDictionary> <local:MainMenuViewModel x:Key="mainMenuViewModel"/> </ResourceDictionary> </ContentPage.Resources>

    In this case, the class name of my view model is "MainMenuViewModel" and the name of the class instance is "mainMenuViewModel".

  • KieranPierceKieranPierce GBMember

    Ok cool thanks for that, did not know it was possible

  • Pierre-ChristopheDusPierre-ChristopheDus FRUniversity ✭✭✭

    @rarenivar
    I tried to do the samething than you, but I get an exception:
    "Xamarin.Forms.Xaml.XamlParseException: Position 8:6. Property Resources is null or is not IEnumerable"

    I create the ViewModel object in the XAML file...
    <xamarinForms:NavegarContentPage.Resources> <ResourceDictionary> <local:ViewModels.DebugPageViewModel x:Key="debugPageViewModel" /> </ResourceDictionary> </xamarinForms:NavegarContentPage.Resources>

    The ListView is like this:
    <ListView Grid.Row="1" ItemsSource="{Binding Families}"> <ListView.ItemTemplate> <DataTemplate> <ViewCell x:Name="ViewCell"> <ViewCell.View> <StackLayout> <Label Text="With"> <Label.GestureRecognizers> <TapGestureRecognizer Command="{Binding Source={StaticResource debugPageViewModel}, Path=WithTappedCommand}" /> </Label.GestureRecognizers> </Label> <Label Text="{Binding Title}" /> <Label Text="Without"> <Label.GestureRecognizers> <TapGestureRecognizer Command="{Binding WithOutTappedCommand}"/> </Label.GestureRecognizers> </Label> </StackLayout> </ViewCell.View> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView>

    And my ViewModel is like this:
    `public class DebugPageViewModel : ViewModelServices
    {
    private ObservableCollection _families;
    public ObservableCollection Families
    {
    get { return _families; }
    set
    {
    _families = value;
    RaisePropertyChanged(() => Families);
    }
    }

    public ICommand WithTappedCommand { get; set; }
    public ICommand WithoutTappedCommand { get; set; }
    
    public DebugPageViewModel()
    {
        LoadDatas();
        WithTappedCommand = new Command(() =>
        {
    
        });
        WithoutTappedCommand = new Command(() =>
        {
    
        });
    }`
    

    Would you have an idea?

  • rarenivarrarenivar USMember ✭✭

    @Pierre-ChristopheDus - It appears the error you're getting is due to the property at line 8 being not defined or null.
    Did you add the namespace of your ViewModel object in your contentpage attributes? Here's how I did it in mine...

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="MyProject.Views.SearchView"
                 xmlns:local="clr-namespace:MyProject.ViewModels;assembly=MyProject"
                 Title=" Search">
    
      <ContentPage.Resources>
        <ResourceDictionary>
          <local:SearchViewModel x:Key="searchViewModel"/>
        </ResourceDictionary>
      </ContentPage.Resources>
    
    
    <!-- your content here -->
    
    
    </ContentPage>
    

    Notice the attribute 'xmlns:local' setting local to the 'MyProject.ViewModels' namespace. Then, I use local when defining the resource dictionary.

  • Pierre-ChristopheDusPierre-ChristopheDus FRUniversity ✭✭✭

    @rarenivar
    Thanks for your return.
    I've done exactly the same thing than you, as I mentioned on a new topic:
    https://forums.xamarin.com/discussion/62641/exceptions-with-resourcedictionary-in-a-contentpage?new=1

    I've got 2 different exceptions for 2 similar cases:
    <?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:vm="clr-namespace:DebugSample.ViewModels;assembly=DebugSample.ViewModels" x:Class="DebugSample.Pages.DebugPage"> <ContentPage.Resources> <ResourceDictionary> <vm:DebugPageViewModel x:Key="debugPageViewModel" /> </ResourceDictionary> </ContentPage.Resources> ... </ContentPage>
    => but this throws an exception: "System.IO.FileNotFoundException: Could not load file or assembly 'DebugSample.ViewModels' or one of its dependencies"

    <?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:local="clr-namespace:DebugSample;assembly=DebugSample" x:Class="DebugSample.Pages.DebugPage"> <ContentPage.Resources> <ResourceDictionary> <local:ViewModels.DebugPageViewModel x:Key="debugPageViewModel" /> </ResourceDictionary> </ContentPage.Resources> ... </ContentPage>
    => I get another exception: "Xamarin.Forms.Xaml.XamlParseException: Position 8:6. Property Resources is null or is not IEnumerable"

    I don't undestand why it doesn't work, cause I can do this in the App.xaml without any problem...
    <?xml version="1.0" encoding="utf-8" ?> <Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:vm="clr-namespace:DebugSample.ViewModels;assembly=DebugSample.ViewModels" x:Class="DebugSample.App"> <Application.Resources> <ResourceDictionary> <vm:ViewModelLocator x:Key="Locator" /> </ResourceDictionary> </Application.Resources> </Application>

  • rarenivarrarenivar USMember ✭✭

    @Pierre-ChristopheDus - Try this...

    <?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:vm="clr-namespace:DebugSample.ViewModels;assembly=DebugSample" 
                 x:Class="DebugSample.Pages.DebugPage">
      <ContentPage.Resources>
        <ResourceDictionary>
          <vm:DebugPageViewModel x:Key="debugPageViewModel" />
        </ResourceDictionary>
      </ContentPage.Resources>
      ...
    </ContentPage>
    
  • Pierre-ChristopheDusPierre-ChristopheDus FRUniversity ✭✭✭
    edited March 2016

    @rarenivar
    Yes it's good likes this!
    But why is this syntax working in the App.xaml, but not in the page?
    xmlns:vm="clr-namespace:DebugSample.ViewModels;assembly=DebugSample.ViewModels"

  • rarenivarrarenivar USMember ✭✭

    @Pierre-ChristopheDus - Is the namespace correctly spelled? Perphaps it's "DebugSample.ViewModel" instead of "DebugSample.ViewModels". What about your DebugPageViewModel file? Is that file in the "DebugSample.ViewModels" namespace? I would double check all of this based on the error you're getting.

  • rarenivarrarenivar USMember ✭✭

    @Pierre-ChristopheDus - Great! I'm glad it's working for you now.

    I would think that your App.xaml file wouldn't work since the assembly is not correctly defined, but somehow it is!
    If you can, try and set the assembly attribute of your App.xaml file the same as your DebugPage, I suspect it would work.

  • joaobp7joaobp7 BRMember ✭✭

    @rarenivar - Thank you for sharing the solution, it worked perfect for me!

Sign In or Register to comment.