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.
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:
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");
}
}
}
<?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>
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;
}
}
}
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!