ContentView 获取选择器的值

问题描述 投票:0回答:1

我遇到的问题是ContentPageView中的标签没有像不使用ContentView时那样显示选择的值。我尝试了不同的方法,但似乎没有任何效果,有什么建议可以告诉我,我可能遗漏了什么?

注:简化的代码删除了不必要的参数。这是一个经常被重复使用的自定义控件,它有更多的组件,与手头这个问题无关

PickerContentView.xaml

<?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="Test.Core.Views.Templates.PickerContentView">
    <ContentView.Content>
        <Grid>
            <Picker x:Name="CustomPicker" />
        </Grid>
    </ContentView.Content>
</ContentView>

PickerContentView.xaml.cs

namespace Test.Core.Views.Templates
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class PickerContentView: ContentView
    {
        public static readonly BindableProperty TitleProperty = BindableProperty.Create(nameof(Title), typeof(string), typeof(PickerContentView), string.Empty);
        public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(nameof(ItemsSource), typeof(IList), typeof(PickerContentView), default(IList));
        public static readonly BindableProperty ItemDisplayBindingProperty = BindableProperty.Create(nameof(ItemDisplayBinding), typeof(string), typeof(PickerContentView), string.Empty);
        public static readonly BindableProperty SelectedItemProperty = BindableProperty.Create(nameof(SelectedItem1), typeof(object), typeof(PickerContentView), default);

        public string Title
        {
            get => (string)GetValue(PickerContentView.TitleProperty);
            set => SetValue(PickerContentView.TitleProperty, value);
        }

        public IList ItemsSource
        {
            get => (IList)GetValue(PickerContentView.ItemsSourceProperty);
            set => SetValue(PickerContentView.ItemsSourceProperty, value);
        }

        public string ItemDisplayBinding
        {
            get => (string)GetValue(PickerContentView.ItemDisplayBindingProperty);
            set => SetValue(PickerContentView.ItemDisplayBindingProperty, value);
        }

        public object SelectedItem1
        {
            get => GetValue(PickerContentView.SelectedItemProperty);
            set => SetValue(PickerContentView.SelectedItemProperty, value);
        }

        public PickerContentView()
        {
            InitializeComponent();
        }

        protected override void OnPropertyChanged(string propertyName)
        {
            base.OnPropertyChanged(propertyName);

            if (propertyName == TitleProperty.PropertyName)
                CustomPicker.Title = Title;
            if (propertyName == ItemsSourceProperty.PropertyName)
                CustomPicker.ItemsSource = ItemsSource;
            if (propertyName == ItemDisplayBindingProperty.PropertyName)
                CustomPicker.ItemDisplayBinding = new Binding(ItemDisplayBinding);
            if (propertyName == SelectedItemProperty.PropertyName)
                CustomPicker.SelectedItem = SelectedItem1;
        }
    }
}

ContentPageView.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:viewModelBase="clr-Test.Core.ViewModels.Base;assembly=Test.Core"
             xmlns:templates="clr-Test.Core.Views.Templates;assembly=Test.Core"
             x:Class="Test.Core.Views.ContentPage"
             viewModelBase:ViewModelLocator.AutoWireViewModel="true"
             Title="Test">
    <ContentPage.Content>
        <ScrollView>
            <StackLayout>
                <templates:PickerContentView Title="Picker List"
                                             ItemsSource="{Binding ListObjects}"
                                             ItemDisplayBinding="Name"
                                             SelectedItem1="{Binding CustomObject, Mode=TwoWay}" />
                <Label Text="{Binding CustomObject.Name}" />
            </StackLayout>
        </ScrollView>
    </ContentPage.Content>
</ContentPage>

内容页视图.xaml.cs

namespace Test.Core.Views
{
    public partial class ContentPageView: ContentPage
    {
        public ContentPageView()
        {
            InitializeComponent();
        }
    }
}

ContentPageView.xaml.cs

namespace Test.Core.ViewModels
{
    public class CustomPageViewModel : ViewModelBase
    {
        private readonly IService _service;
        private ObservableCollection<CustomObject> _listObjects;
        private CustomObject _customObject;

        public ObservableCollection<CustomObject> ListObjects
        {
            get { return _listObjects; }
            set
            {
                _listObjects= value;
                RaisePropertyChanged(() => ListObjects);
            }
        }

        public CustomObject CustomObject
        {
            get { return _customObject; }
            set
            {
                _customObject= value;
                RaisePropertyChanged(() => CustomObject);
            }
        }

        public CustomPageViewModel(IService service)
        {
            _service = service;
        }

        public override async Task InitializeAsync()
        {
            IsBusy = true;
            ListObjects= await _service.GetListObjectsAsync();
            IsBusy = false;
        }
    }
}
c# xaml xamarin xamarin.forms
1个回答
0
投票

你需要实现 propertyChnaged 中的可绑定属性的委托。PickerContentView

public static readonly BindableProperty SelectedItemProperty = BindableProperty.Create(propertyName: nameof(SelectedItem1),
                                                                                        returnType: typeof(object),
                                                                                        declaringType: typeof(PickerContentView),
                                                                                        defaultValue: default,
                                                                                        propertyChanged: SelectedItem1Changed);

private static void SelectedItem1Changed(BindableObject bindable, object oldValue, object newValue)
{
    var thisView = bindable as PickerContentView;
    thisView.CustomPicker.SelectedItem = newValue ;
}

此外,看起来像绑定似乎是错误的,SelectedItem应该在绑定的ItemsSource中找到,在你的情况下,看起来你是分配给一个新的对象。CustomPageViewModel.CustomObject 相对于 CustomPageViewModel.ListObjects[n] 如果对象是不同的,可能就不会成功。然后在 SelectedItem1Changed 便是

private static void SelectedItem1Changed(BindableObject bindable, object oldValue, object newValue)
{
    var thisView = bindable as PickerContentView;
    var temp = thisView.CustomPicker.ItemsSource.Cast<object>().FirstOrDefault(x=>x == newObject);
    if(temp != null)
          thisView.CustomPicker.SelectedItem = temp ;
}

我建议你加上 SelectIndex 的属性,以 PickerContentView

© www.soinside.com 2019 - 2024. All rights reserved.