Где установить привязки для пользовательской ячейки с помощью средства визуализации клиента, если я использую DataTemplateSelector?

У меня есть DataTemplateSelector, который выбирает между двумя разными ячейками. В Android этот шаблон выбирает ячейки, определенные как XML-файлы Android. Я могу подтвердить, что селектор шаблонов работает, потому что у меня отображаются два разных цветных круга, и цвета правильные. Но мои данные не связаны, и я не уверен, почему. Я думаю, что я где-то не устанавливаю привязку, но я не уверен, где/как это сделать.

Вот моя страница, которая включает ListView с DataTemplateSelector. Я устанавливаю ItemsSource здесь, но никогда не устанавливаю привязки для разных частей элементов списка. Вот и не знаю что делать.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyApp.Pages.Routines.TopLevelRoutinesPage"
             xmlns:statics="clr-namespace:MyApp.Statics;assembly=MyApp"
             xmlns:controls="clr-namespace:MyApp.Controls;assembly=MyApp">
  <ContentPage.Resources>
    <ResourceDictionary>
      <controls:RoutinesDataTemplateSelector x:Key="RoutinesDataTemplateSelector"></controls:RoutinesDataTemplateSelector>
    </ResourceDictionary>
  </ContentPage.Resources>
  <ContentPage.Content>
    <StackLayout VerticalOptions="FillAndExpand"
                 HorizontalOptions="FillAndExpand"
                 Orientation="Vertical"
                 Spacing="0">
      <ListView ItemsSource="{Binding SelectedRoutineTree}"
                ItemTemplate="{StaticResource RoutinesDataTemplateSelector}"
                x:Name="RoutinesView"
                ItemSelected="RoutineClicked"
                Margin ="0, 8, 0, 0">
      </ListView>
    </StackLayout>
  </ContentPage.Content>
</ContentPage>

Код позади:

using MyApp.ViewModels;
using MyCloudContracts.DTOs;
using System;
using System.Linq;
using Xamarin.Forms;

namespace MyApp.Pages.Routines
{
    public partial class TopLevelRoutinesPage : ContentPage
    {
        private TopLevelRoutinesViewModel _viewModel;
        private string _projCompName;

        public TopLevelRoutinesPage(Guid docId, bool fromCompany, string projCompName)
        {
            InitializeComponent();
            _projCompName = projCompName;
            Title = _projCompName;
            _viewModel = new TopLevelRoutinesViewModel(docId, fromCompany);
            BindingContext = _viewModel;

            if (Device.OS == TargetPlatform.Android)
                RoutinesView.SeparatorVisibility = SeparatorVisibility.None;
        }

        private async void RoutineClicked(object sender, SelectedItemChangedEventArgs e)
        {
            //since this is also called when an item is deselected, return if set to null
            if (e.SelectedItem == null)
                return;

            var selectedRoutine = (PublishedDocumentFragmentDTO)e.SelectedItem;
            var fragId = selectedRoutine.FragmentId;
            var title = selectedRoutine.Title;
            var blobIdStr = selectedRoutine.BlobId;
            var blobId = new Guid(blobIdStr);

            if (selectedRoutine.Children.Any())
            {
                var routineTree = _viewModel.SelectedRoutineTree;
                var subroutinesPage = new SubroutinesPage(routineTree, fragId, title, blobId, _projCompName);
                await Navigation.PushAsync(subroutinesPage);
            }
            else
            {
                var routinePage = new RoutinePage(title, blobId);
                await Navigation.PushAsync(routinePage);
            }

            //take away selected background
            ((ListView)sender).SelectedItem = null;
        }
    }
}

DataTemplateSelector

using MyApp.Pages.Routines.CustomCells;
using MyCloudContracts.DTOs;
using Xamarin.Forms;

namespace MyApp.Controls
{
    class RoutinesDataTemplateSelector : DataTemplateSelector
    {
        private readonly DataTemplate _folderDataTemplate;
        private readonly DataTemplate _routineDataTemplate;

        public RoutinesDataTemplateSelector()
        {
            _folderDataTemplate = new DataTemplate(typeof(FolderViewCell));
            _routineDataTemplate = new DataTemplate(typeof(RoutineViewCell));
        }

        protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
        {
            var chooser = item as PublishedDocumentFragmentDTO;
            if (chooser == null)
                return null;
            else if (chooser.Children.Length == 0)
            {
                return _routineDataTemplate;
            }
            else
            {
                return _folderDataTemplate;
            }      
        }
    }
}

И пример одной из моих пользовательских ViewCell. Я думаю, что здесь я ошибаюсь, но я не уверен, почему. Я делаю свойства, но я не знаю, как их правильно установить.

using Xamarin.Forms;

namespace MyApp.Pages.Routines.CustomCells
{
    public class RoutineViewCell : ViewCell
    {
        public static readonly BindableProperty TitleProperty =
            BindableProperty.Create("Title", typeof(string), typeof(RoutineViewCell), "");

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

Спасибо за помощь :)


person Jason Toms    schedule 11.11.2016    source источник


Ответы (1)


Я нашел ответ. Мне нужно было переопределить OnBindingContextChanged() в пользовательском файле ячейки. Мой рабочий код сейчас выглядит так:

using Xamarin.Forms;

namespace MyApp.Pages.Routines.CustomCells
{
    public class RoutineViewCell : ViewCell
    {
        public static readonly BindableProperty TitleProperty =
            BindableProperty.Create("Title", typeof(string), typeof(RoutineViewCell), "");

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

        protected override void OnBindingContextChanged()
        {
            this.SetBinding(TitleProperty, "Title");
            base.OnBindingContextChanged();
        }
    }
}
person Jason Toms    schedule 11.11.2016