首页 > 解决方案 > 如何在 Xamarin.Forms 中访问自定义控件的 BindingContext

问题描述

我有一个 CollectionView,其中 ItemsSource 设置为 Employee 类型的 ObservableCollection。CollectionView 的 ItemTemplate 是一个 CustomControl,它有 1 个 Employee 类型的 BindableProperty

MainPage.xaml:

  <CollectionView ItemsSource="{Binding Employees}"
                  SelectedItem="{Binding SelectedEmployee}">
    <CollectionView.ItemTemplate>
      <DataTemplate>
        <controls:CustomControl Employee="{Binding .}" />
      </DataTemplate>
    </CollectionView.ItemTemplate>
  </CollectionView>

CustomControl 有一个图像(选中的图像表示选择)。

自定义控件.xaml:

  <Frame HasShadow="True"
         BackgroundColor="Blue">
    <StackLayout Orientation="Horizontal">
      <Label Text="{Binding Name}" />
      <Image Source="check.png" />
    </StackLayout>
  </Frame>

CustomControl.xaml.cs:

public partial class CustomControl : ContentView
    {
        public CustomControl()
        {
            InitializeComponent();
        }

        public static BindableProperty EmployeeProperty = BindableProperty.Create(
                    propertyName: nameof(Employee),
                    returnType: typeof(Employee),
                    declaringType: typeof(CustomControl),
                    defaultValue: default(Employee),
                    defaultBindingMode: BindingMode.OneWay);

        public Employee Employee
        {
            get
            {
                return (Employee)GetValue(EmployeeProperty);
            }
            set
            {
                SetValue(EmployeeProperty, value);
            }
        }
    }

模特(员工):

public class Employee: INotifyPropertyChanged
    {
        private int name;
        public int Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
                OnPropertyChanged(nameof(Name));
            }
        }


        private int isSelected;
        public int IsSelected
        {
            get
            {
                return isSelected;
            }
            set
            {
                isSelected = value;
                OnPropertyChanged(nameof(IsSelected));
            }
        }

        #region PropertyChanged
        public void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }

I am trying to create simple animation (FadeIn/FadeOut) for the checked image in the CustomControl so when an item is selected the image will fade in, and when unselected it will fade out. 我可以使用 IsVisible 并将其设置为 true/false,但这很难看。我的想法是监听 Employee 的 PropertyChanged 事件(它应该是我的 CustomControl 的上下文),当属性 IsSelected 被修改时,我将启动动画来显示/隐藏图像。像这样的东西

public CustomControl()
        {
            InitializeComponent();
            (this.BindingContext as Employee).PropertyChanged += CustomControl_PropertyChanged;
        }

        private void CustomControl_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(Employee.IsSelected))
            {
                //do animation to show/hide image
            }
        }

但无法访问我的 CustomControl 的上下文!当我在 MainPage.xaml 中声明绑定时,我将单个 Emplyee 对象作为 BindingContext 传递(那个点,对吗?):

<controls:CustomControl Employee="{Binding .}" />

但是CustomControl初始化后,BindingContext仍然为空!

public CustomControl()
        {
            InitializeComponent();
            var context = this.BindingContext; //this is null
        }

如何从我的 CustomControl 观察 Employee 对象的 IsSelected 属性的变化?

标签: xamarin.forms

解决方案


在您的自定义控件中重写 OnBindingContextChanged 方法,在该方法内部,您应该能够访问为您的视图设置的绑定上下文。

前任:

    protected override void OnBindingContextChanged()
    {
        base.OnBindingContextChanged();
        var context = this.BindingContext as Employee
    }

推荐阅读