ContentView выбирает выбранное значение - PullRequest
0 голосов
/ 29 апреля 2020

У меня проблема в том, что метка в 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>

ContentPageView.xaml.cs

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

ContentPageViewModel.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;
        }
    }
}

1 Ответ

0 голосов
/ 29 апреля 2020

Вам необходимо реализовать 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, в вашем case выглядит так, как будто вы присваиваете новый объект 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...