如何通过Xamarin形式的绑定使用可绑定属性?

时间:2018-09-05 14:33:42

标签: c# xaml xamarin.forms controls

我试图创建一个包含具有特殊设计的选择器的内容视图,并编写所有可绑定的属性,如下所示:

<?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 :(得分:1)

您需要为根定义一个名称,然后引用根的绑定。

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