获取控件中 ViewModel 中使用的 BindableProperty 的值?

Get value of a BindableProperty used in ViewModel in control?

我有一个 Control,我在其中定义了 bool 类型的 BindableProperty。此 BindablePropertyViewModel 使用:如何从我的控件中获取此 属性 在 ViewModel 中的值?

例如,在ViewModel中我给它赋值false,在控件中我想得到它的值,如果它是假的,它会做一些事情。

我的代码

自定义控件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) });
                }
        
        }

我不确定这是否真的可行,如果不行,有没有办法调用在 ViewModel 中的控件上创建的方法?

使用 BindableProperty 的 属性Changed 属性。您可以修改您的代码如下:

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
            }
        }

        

    }

为了演示这是如何工作的,我创建了一个完整的简单示例:

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>

代码隐藏 (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;
        }
    }
}

查看模型

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));
        }
    }

}

如果您还有其他问题,请告诉我们!

编码愉快!