Forum Xamarin.Forms

Change another control property on tap

mmshmmsh Member ✭✭
edited July 2020 in Xamarin.Forms

Hi
I have an image in a ListView that have Source property . How can I change Source property when another image in same ListView tapped ?

I want Tap on ffimageLoading in CarouselView and Source property of Image in StackLayout will change . both CarouselView and StackLayout are in CollectionView

Best Answer

  • ColeXColeX Member, Xamarin Team Xamurai
    edited July 2020 Accepted Answer
    1. Model class needs to implement INotifyPropertyChanged .

       public class FPostModel : INotifyPropertyChanged
       {
          public event PropertyChangedEventHandler PropertyChanged;
          protected void OnPropertyChanged([CallerMemberName] string name = null)
          {
              PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
          }
      
          private string _likedImage;
          public string likedImage {
              get {
                  return _likedImage;
              } set {
                  _likedImage = value;
                  OnPropertyChanged();
              } }
        }
      
    2. Put likeTapCommand inside model class FPostModel not HomeViewModel .

    3. Change likedImage in callback method of likeTapCommand .

Answers

  • mmshmmsh Member ✭✭

    anyone can help ?

  • ColeXColeX Member, Xamarin Team Xamurai

    @mmsh Could you post the complete code (viewmodel )?

  • mmshmmsh Member ✭✭
    edited July 2020

    Hi @ColeX

    this is my ViewModel

    public class HomeViewModel : ViewModelBase
        {
        private ObservableCollection<FPostModel> _Post;
            public ObservableCollection<FPostModel> Post
            {
                get => _Post;
                set
                {
                    SetValue(ref _Post, value);
                    OnPropertyChanged("Post");
                }
            }
    
           ICommand likeTapCommand;
            public ICommand LikeTapCommand
            {
                get { return likeTapCommand; }
            }
    
            public HomeViewModel()
            {
                likeTapCommand = new Command(ExecuteLikeTap);
    
                Post = new ObservableCollection<FPostModel>();
            }
    
            protected void ExecuteLikeTap(object l)
            {
                string token = SecureStorage.GetAsync("oauth_token").Result;
    
                int id = Convert.ToInt32(l);
    
                var nsAPI = RestService.For<IAdvApi>(GetUrl.GenerateURL("URL"));
                var response = nsAPI.LikePost("Bearer " + token, id);
            }
        }
    

    But I want to change property in Code Behind

    private void Like(object sender, System.EventArgs e)
            {
                Image image = sender as Image;
                var sourve = image.Source as FileImageSource;
    
                if (sourve.File == "heart2.png")
                    image.Source = ImageSource.FromFile("heart.png");
                else
                    image.Source = ImageSource.FromFile("heart2.png");
            }
    
  • ColeXColeX Member, Xamarin Team Xamurai

    The easiest way is to use messaging center , send the message in Like method and receive in the model which own the property LikedImage , modify the data when tapping on ffimageLoading in CarouselView .

  • mmshmmsh Member ✭✭
    edited July 2020

    @ColeX said:
    The easiest way is to use messaging center , send the message in Like method and receive in the model which own the property LikedImage , modify the data when tapping on ffimageLoading in CarouselView .

    Thanx for yor reply . LikedImage owned by an ObservableCollection that name is Post . How can I receive message and pass it to LikedImage that is in an ObservableCollection and save ?

  • mmshmmsh Member ✭✭

    Can you help me @ColeX

  • ColeXColeX Member, Xamarin Team Xamurai
    edited July 2020 Accepted Answer
    1. Model class needs to implement INotifyPropertyChanged .

       public class FPostModel : INotifyPropertyChanged
       {
          public event PropertyChangedEventHandler PropertyChanged;
          protected void OnPropertyChanged([CallerMemberName] string name = null)
          {
              PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
          }
      
          private string _likedImage;
          public string likedImage {
              get {
                  return _likedImage;
              } set {
                  _likedImage = value;
                  OnPropertyChanged();
              } }
        }
      
    2. Put likeTapCommand inside model class FPostModel not HomeViewModel .

    3. Change likedImage in callback method of likeTapCommand .

  • mmshmmsh Member ✭✭
    edited July 2020

    @ColeX said:
    1. Model class needs to implement INotifyPropertyChanged .

         public class FPostModel : INotifyPropertyChanged
         {
            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged([CallerMemberName] string name = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
            }
    
            private string _likedImage;
            public string likedImage {
                get {
                    return _likedImage;
                } set {
                    _likedImage = value;
                    OnPropertyChanged();
                } }
          }
    
    1. Put likeTapCommand inside model class FPostModel not HomeViewModel .

    2. Change likedImage in callback method of likeTapCommand .

    Hi @ColeX

    Thanx for your reply . Excuse me for delay

    BindingContext of CollectionView is HomeViewModel and in it I Load data when page is Call and Image control read likedImage from an ObservableCollection in that . How can I change likedImage in Model when BindingContext is ViewModel ?

  • mmshmmsh Member ✭✭
    edited July 2020

    @ColeX said:
    1. Model class needs to implement INotifyPropertyChanged .

         public class FPostModel : INotifyPropertyChanged
         {
            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged([CallerMemberName] string name = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
            }
    
            private string _likedImage;
            public string likedImage {
                get {
                    return _likedImage;
                } set {
                    _likedImage = value;
                    OnPropertyChanged();
                } }
          }
    
    1. Put likeTapCommand inside model class FPostModel not HomeViewModel .

    2. Change likedImage in callback method of likeTapCommand .

    as @ColeX said I implemented INotifyPropertyChanged in Model class (FPostModel) and change ExecuteLikeTap command in ViewModel

    `
    protected void ExecuteLikeTap(object l)
    {
    var lbl = l as Label;

             string token = SecureStorage.GetAsync("oauth_token").Result;
    
             int id = Convert.ToInt32(lbl.Text);
    
             var post = Post.Where(p => p.id == id).Single();
    
             if (post.likedImage == "heart.png")
             {
                 post.likedImage = "heart2.png";
             }
    
             else
             {
                 post.likedImage = "heart.png";
             }
    
             var nsAPI = RestService.For<IAdvApi>(GetUrl.GenerateURL("URL"));
             var response = nsAPI.LikePost("Bearer " + token, id);
        }
    

    `

    But fore retrieving Post Id I used a hidden Lable in XAML and bind Post.id to it's text and in TapGestureRecognizer send it as parameter . I believe it is wrong way . Any body can help me in this case ?

Sign In or Register to comment.