【问题标题】:How do I display picker control items within a custom control?如何在自定义控件中显示选取器控件项?
【发布时间】:2020-06-09 14:28:00
【问题描述】:

如何在自定义控件中显示选取器控件项?

我可以毫无问题地绑定到选择器的标题属性。 但是,我无法让 ItemsSource 绑定工作,以便我可以观察选择器的选择。

LabelPickerPair.xaml:

<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
    x:Class="NewAssessment.UI.LabelPickerPair"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:d="http://xamarin.com/schemas/2014/forms/design"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    x:Name="ParentControl"
    mc:Ignorable="d">
    <ContentView.Content>
        <StackLayout>
            <Label FontSize="Medium" Text="{Binding Source={x:Reference ParentControl}, Path=LabelText}" />
            <Picker
                Title="{Binding Source={x:Reference ParentControl}, Path=Title}"
                FontSize="Large"
                ItemsSource="{Binding Source={x:Reference ParentControl}, Path=ItemsSource}"
        </StackLayout>
    </ContentView.Content>
</ContentView>

LabelPickerPair.xaml.cs:

namespace NewAssessment.UI
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class LabelPickerPair : ContentView
    {
        public LabelPickerPair() => InitializeComponent();

        public static BindableProperty TitleProperty = BindableProperty.Create(
                propertyName: nameof(Title),
                returnType: typeof(string),
                declaringType: typeof(LabelPickerPair),
                defaultValue: "",
                defaultBindingMode: BindingMode.TwoWay);

        public string Title
        {
            get { return (string)GetValue(TitleProperty); }
            set
            {
                SetValue(TitleProperty, value);
            }
        }

        public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(
            nameof(ItemsSource), 
            typeof(IList ), 
            typeof(LabelPickerPair),
            defaultBindingMode: BindingMode.TwoWay,
            propertyChanged: OnItemsSourceChanged);

        static void OnItemsSourceChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var thisControl = bindable as LabelPickerPair;

            if (oldValue != null)
                thisControl.ItemsSource = oldValue as IList ;

            if (newValue != null)
                thisControl.ItemsSource = newValue as IList ;
        }

        public IList  ItemsSource
        {
            get { 
                    var items = (IList)GetValue(ItemsSourceProperty);
                    return items; 
                }

            set { SetValue(ItemsSourceProperty, value); }
        }
    }
}

【问题讨论】:

  • 我的回答对你有用吗?

标签: xamarin.forms


【解决方案1】:

我写了一个演示,它适用于我,你可以在这里查看我的代码,找出与你的不同之处:

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();

        this.BindingContext = new testModel();

    }
}

public class testModel : INotifyPropertyChanged
{

    public testModel() {

        this.Title = "testTitle";
        this.ItemsSource = new List<string>()
        {
            "1","2","3","4","5","6","7"
        };
    }

    string title { get; set; }
    public string Title
    {
        set
        {
            if (title != value)
            {
                title = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("DateTime"));
                }
            }
        }
        get
        {
            return title;
        }
    }

    IList itemsSource { get; set; }
    public IList ItemsSource
    {
        set
        {
            if (itemsSource != value)
            {
                itemsSource = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("ItemsSource"));
                }
            }
        }
        get
        {
            return itemsSource;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

在 Xaml 中:

<StackLayout Padding="20,20,20,30">
    <app267:View1 >
    </app267:View1>
</StackLayout>

在 View1 中,我将路径更改为 BindingContext.Title 和 BindingContext.ItemsSource:

<ContentView.Content>
    <StackLayout>
        <Label FontSize="Medium" Text="text" />
        <Picker
            Title="{Binding Source={x:Reference ParentControl}, Path= BindingContext.Title}"
            FontSize="Large"
            ItemsSource="{Binding Source={x:Reference ParentControl}, Path=BindingContext.ItemsSource}"/>
    </StackLayout>
</ContentView.Content>

我上传了我的示例项目here,欢迎随时问我任何问题。

【讨论】:

  • 谢谢杰克。我求助于 ValueConverters 来解决我的问题。我目前没有时间进一步调查。但是,即使我没有尝试过,我也会将您的帖子标记为答案。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-16
  • 2020-03-29
  • 1970-01-01
  • 1970-01-01
  • 2018-02-23
  • 1970-01-01
相关资源
最近更新 更多