简体   繁体   中英

Get value of a BindableProperty used in ViewModel in control?

I have a Control where i define a BindableProperty of type bool . This BindableProperty is used by the ViewModel : How can I get the value this property has in the ViewModel from my control?

For example, in the ViewModel I assign it false , in the control I want to get its value and if it is false, it does something.

My code

Custom Control xaml cs:

 public static readonly BindableProperty CustomEmojisProperty =
            BindableProperty.Create("CustomEmojis", typeof(bool), typeof(Editor), propertyChanged: OnPropertyChanged);

    public bool CustomEmojis
    {
        get { return (bool)GetValue(CustomEmojisProperty); }
        set { SetValue(CustomEmojisProperty, value); }
    }

    private static void OnPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {

        var editor = bindable as Editor;

        if (((Editor)bindable).CustomEmojis == false)
        {

            ObservableCollection<Emojis> EmojiList = new ObservableCollection<Emojis>();

            editor.collectionView.ItemsSource = EmojiList;

            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.SlightlySmilingFace) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.FaceWithStuckOutTongueAndWinkingEye) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.LoudlyCryingFace) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.WinkingFace) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.SmilingFaceWithHeartEyes) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.OkHand) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.ThumbsUp) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.ThumbsDown) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.UpsideDownFace) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.CryingFace) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.FaceWithColdSweat) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.FlexedBiceps) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.NeutralFace) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.FaceScreamingInFear) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.FaceWithTearsOfJoy) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.BackhandIndexPointingUp) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.GrinningFace) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.MoneyMouthFace) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.OpenHands) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.RaisedFist) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.RaisedHand) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.RelievedFace) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.PensiveFace) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.SmilingFaceWithOpenMouth) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.SmilingFaceWithOpenMouthAndSmilingEyes) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.SmilingFaceWithOpenMouthAndClosedEyes) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.SmilingFaceWithOpenMouthAndColdSweat) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.VulcanSaluteLightSkinTone) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.SmilingFaceWithSunglasses) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.FaceWithStuckOutTongue) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.FaceWithStuckOutTongueAndClosedEyes) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.RaisingHands) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.UnamusedFace) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.IndexPointingUp) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.VictoryHand) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.WavingHand) });
            EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.SignOfTheHornsMediumLightSkinTone) });

        }
    }

Mainpage.xaml:

 <fav1:Control CustomEmojis="{Binding CustomEmojis}"/>

Mainpage.cs:

  public MainPage()
    {
        InitializeComponent();
        Xamarin.Forms.Application.Current.On<Android>().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);
        BindingContext = new EmojiViewModel();
    }

ViewModel.xaml.cs:

   public event PropertyChangedEventHandler PropertyChanged;
    
            protected virtual void OnPropertyChanged(string propertyName = "")
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
    
  ObservableCollection<Emojis> emojilist;
        public ObservableCollection<Emojis> EmojiList
        {
            get => emojilist; set
            {
                emojilist = value;
                OnPropertyChanged();
            }
        }

        bool customemojis;
        public bool CustomEmojis {
          get =>customemojis;
          set {
            customemojis = value;
            OnPropertyChanged();
          }
        }
        
        public ViewModel() {
          CustomEmojis = true;
        
          if (CustomEmojis == true)
                {
                    EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.Niger) });
                    EmojiList.Add(new Emojis { EmojiSource = Convert.ToString(Emoji.Kiss) });
                }
        
        }

I'm not sure if this is actually possible to do, if not, is there a way to call a method created on the control in the ViewModel?

Use the propertyChanged property of the BindableProperty. You can modify your code as follows:

class Control : BindableObject
    {

        public static readonly BindableProperty CustomEmojisProperty =
                BindableProperty.Create("CustomEmojis", typeof(bool), typeof(Editor), propertyChanged: OnPropertyChanged);

        public bool CustomEmojis
        {
            get { return (bool)GetValue(CustomEmojisProperty); }
            set { SetValue(CustomEmojisProperty, value); }
        }

        private static void OnPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            if (((Control)bindable).CustomEmojis == false)
            {

                //do something
            }
        }

        

    }

To demonstrate how this works i created a whole simple sample:

Control.cs

using Xamarin.Forms;

namespace PickerOC
{

    class Control : Label
    {

        public static readonly BindableProperty CustomEmojisProperty =
                BindableProperty.Create("CustomEmojis", typeof(bool), typeof(Editor), propertyChanged: OnPropertyChanged);

        public bool CustomEmojis
        {
            get { return (bool)GetValue(CustomEmojisProperty); }
            set { SetValue(CustomEmojisProperty, value); }
        }

        private static async void OnPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            if (((Control)bindable).CustomEmojis == false)

                await Application.Current.MainPage.DisplayAlert("Alert!", "CustomEmoj is false!", "Ok");

            else

                await Application.Current.MainPage.DisplayAlert("Alert!", "CustomEmoj is true!", "Ok");

        }

    }
}

MainPage.xaml

<?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:PickerOC"
             x:Class="PickerOC.MainPage">

    <StackLayout>
        <local:Control x:Name="control"
                       Text="I am the Control!"
                       Padding="20"
                       CustomEmojis="{Binding CustomEmojis}"
                       HorizontalOptions="CenterAndExpand"/>
        
        <Button Text="Change Custom Emoji!!!"
                Clicked="Button_Clicked"/>
    </StackLayout>

</ContentPage>

Code behind (MainPage.xaml.cs)

using System;
using Xamarin.Forms;

namespace PickerOC
{
    public partial class MainPage : ContentPage
    {

        MainPageViewModel viewModel { get; set; }

        public MainPage()
        {
            InitializeComponent();
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();

            viewModel = new MainPageViewModel();
            BindingContext = viewModel;
        }

        private void Button_Clicked(object sender, EventArgs e)
        {

            viewModel.CustomEmojis = !viewModel.CustomEmojis;
        }
    }
}

View Model

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace PickerOC
{
    class MainPageViewModel : INotifyPropertyChanged
    {

        bool customemojis;
        public bool CustomEmojis
        {
            get => customemojis;
            set
            {
                customemojis = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged([CallerMemberName] string name = "")
        {
            var propertyChanged = PropertyChanged;

            propertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }

}

If you have further issues, let us know!

Happy codding!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM