Как использовать свойство bindable при связывании в формах xamarin? - PullRequest
0 голосов
/ 05 сентября 2018

Я пытаюсь создать представление содержимого, содержащее средство выбора со специальным дизайном, и написал все привязываемые свойства, например:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ShobeekClientApp.Custom.Views.Picker">
    <ContentView.Content>
        <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <Picker x:Name="FSPicker" Title="{Binding PickerTitle,Source={x:Reference this}" 
                    ItemsSource="{Binding PickerItemsSource,Source={x:Reference this}}" 
                    ItemDisplayBinding="{Binding PickerItemDisplayBinding,Source={x:Reference this}}"
                    HorizontalOptions="FillAndExpand"/>

        </Grid>
    </ContentView.Content>
</ContentView>

Код содержимого contentView:

using System;
using System.Collections;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace ShobeekClientApp.Custom.Views
{
    ///for more information  follow this tutorial
    ///https://mindofai.github.io/Creating-Custom-Controls-with-Bindable-Properties-in-Xamarin.Forms/
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Picker : ContentView
    {
        #region selected index property
        public static readonly BindableProperty PickerSelectedIndexProperty = BindableProperty.Create(
           nameof(PickerSelectedIndex), typeof(int), typeof(Picker), -1, BindingMode.TwoWay, propertyChanged: selctedIndexChanged);

        private static void selctedIndexChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (Picker)bindable;
            control.FSPicker.SelectedIndex = (int)newValue;
        }

        public int PickerSelectedIndex
        {
            get { return (int)GetValue(PickerSelectedIndexProperty); }
            set { SetValue(PickerSelectedIndexProperty, value); }
        }
        #endregion

        #region title Property
        public static readonly BindableProperty PickerTitleProperty = BindableProperty.Create(
      nameof(PickerTitle), typeof(string), typeof(Picker), defaultValue: "", defaultBindingMode : BindingMode.TwoWay,
      propertyChanged: titleChanged);

        private static void titleChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (Picker)bindable;
            control.FSPicker.Title = newValue.ToString();
        }

        public string PickerTitle
        {
            get { return (string)GetValue(PickerTitleProperty); }
            set { SetValue(PickerTitleProperty, value); }
        }
        #endregion

        #region items source property
        public static readonly BindableProperty PickerItemsSourceProperty = BindableProperty.Create(
            nameof(PickerItemsSource), typeof(IList), typeof(Picker), null, BindingMode.TwoWay, propertyChanged: ItemsSourceChanged);

        private static void ItemsSourceChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (Picker)bindable;
            control.FSPicker.ItemsSource = (IList)newValue;
        }

        public IList PickerItemsSource
        {
            get { return (IList)GetValue(PickerItemsSourceProperty); }
            set { SetValue(PickerItemsSourceProperty, value); }
        }
        #endregion

        public static readonly BindableProperty PickerItemDisplayBindingProperty = BindableProperty.Create(nameof(PickerItemDisplayBinding), typeof(BindingBase), typeof(Picker));
        public BindingBase PickerItemDisplayBinding
        {
            get { return (BindingBase)GetValue(PickerItemDisplayBindingProperty); }
            set { SetValue(PickerItemDisplayBindingProperty, value); }
        }

        public Picker ()
        {
            try
            {
                InitializeComponent();
                BindingContext = this;
                //FSPicker.SetBinding(FSPicker.ItemsSource, new Binding(nameof(Property), source: BindingContext));
                //SetBinding(PickerSelectedIndexProperty, );
            }
            catch (Exception ex)
            {
                var msg = ex.Message;
            }
        }
    }
}

Использование контрольного кода:

<customViwes:Picker PickerTitle="{Binding PickerTitle,Mode=TwoWay}"  `PickerItemsSource="{Binding pickerData,Mode=TwoWay}" PickerItemDisplayBinding="{Binding .}"/>`

Я хочу связать это свойство с другим дизайном, использующим этот элемент управления, используя {Binding}

Если я использую абсолютное значение, оно появляется успешно, и я буду использовать его с привязкой, поскольку я использую структуру MVVM, оно не работает

1 Ответ

0 голосов
/ 05 сентября 2018

Вам нужно определить имя для своего корня, а затем сослаться на привязку корня.

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Name="Root" 
             x:Class="ShobeekClientApp.Custom.Views.Picker">
    <ContentView.Content>
        <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <Picker x:Name="FSPicker" Title="{Binding Source={ x:Reference Root }, Path=PickerTitle}" 
                    ItemsSource="{Binding Source={ x:Reference Root }, Path=PickerItemsSource}" 
                    ItemDisplayBinding="{Binding Source={ x:Reference Root }, Path=PickerItemDisplayBinding}" 
                    HorizontalOptions="FillAndExpand"/>

        </Grid>
    </ContentView.Content>
</ContentView>
...