2016-09-02 4 views
0

У меня есть проблема с пользовательским рендерером. Мой образец основан на образце с официального сайта Xamarin, но я не могу заставить метод OnElementPropertyChanged в рендерере не запускаться, когда я добавляю элемент в связанный список.Xamarin Renderer не отвечает на измененное свойство

Cell:

public class NativeiOSListViewCell : UITableViewCell 
{ 

    UILabel name; 

    public NativeiOSListViewCell(NSString cellId) : base(UITableViewCellStyle.Default, cellId) 
    { 
     SelectionStyle = UITableViewCellSelectionStyle.Gray; 
     ContentView.BackgroundColor = UIColor.FromRGB(218, 255, 127); 
     name = new UILabel() 
     { 
      Font = UIFont.FromName("Cochin-BoldItalic", 22f), 
      TextColor = UIColor.FromRGB(127, 51, 0), 
      BackgroundColor = UIColor.Clear 
     }; 
     ContentView.Add(name); 
    } 

    public void UpdateCell(string caption) 
    { 
     name.Text = caption; 

    } 

    public override void LayoutSubviews() 
    { 
     base.LayoutSubviews(); 
     name.Frame = new CoreGraphics.CGRect(5, 4, ContentView.Bounds.Width - 63, 25); 

    } 

} 

Renderer

[assembly: ExportRenderer(typeof(MyNativeListView), typeof(Blabla.iOS.NativeiOSListViewRenderer))] 
namespace Blabla.iOS 
{ 
    public class NativeiOSListViewRenderer : ListViewRenderer 
    { 
     protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e) 
     { 
      base.OnElementChanged(e); 

      if (e.OldElement != null) 
      { 
       // Unsubscribe 
      } 

      if (e.NewElement != null) 
      { 
       Control.Source = new NativeiOSListViewSource(e.NewElement as MyNativeListView); 
      } 
     } 


     protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) 
     { 
      base.OnElementPropertyChanged(sender, e); 

      if (e.PropertyName == MyNativeListView.ItemsProperty.PropertyName) //Only triggered for stuff like Height, Width and not Items 
      { 
       Control.Source = new NativeiOSListViewSource(Element as MyNativeListView); 
      } 
     } 
    } 
} 

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" x:Class="Blabla.PlayGroundPage" xmlns:local="clr-namespace:Blabla;assembly=Blabla"> 
    <ContentPage.Resources> 
     <ResourceDictionary> 
      <local:Inverter x:Key="inverter" /> 
     </ResourceDictionary> 
    </ContentPage.Resources> 
    <ContentPage.Content> 
     <StackLayout> 
      <local:MyNativeListView x:Name="nativeListView" VerticalOptions="FillAndExpand" Items="{Binding LocalItems}" /> 
      <Button Text="add" Command="{Binding Add}" /> 
     </StackLayout> 
    </ContentPage.Content> 
</ContentPage> 

Код За:

public partial class PlayGroundPage : ContentPage 
{ 
    public PlayGroundPage() 
    { 
     InitializeComponent(); 
     PlayGroundViewModel viewModel = new PlayGroundViewModel(); 
     BindingContext = viewModel; 
    } 
} 

ViewModel

public class PlayGroundViewModel : INotifyPropertyChanged 
{ 
    public ICommand Add { get; private set; } 
    private ObservableCollection<ListItem> _localItems; 
    public ObservableCollection<ListItem> LocalItems { get { return _localItems; } set { _localItems = value; SetChangedProperty("LocalItems"); } } 
    public PlayGroundViewModel() 
    { 
     Add = new Command(() => { AddItem(); }); 
     LocalItems = new ObservableCollection<ListItem>(); 

    } 
    private void AddItem() 
    { 
     ListItem item = new ListItem("a", "b", true); //Just to get something to pop up in the list. 
     LocalItems.Add(item); 
     SetChangedProperty("LocalItems"); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void SetChangedProperty(string property) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(property)); 
     } 
    } 

} 

ListItem

public class ListItem 
{ 

    public string SelectedType { get; set; } 
    public string SelectedOption { get; set; } 
    public bool IsChecked { get; set; } 

    public ListItem(string selectedType, string selectedOption, bool isChecked) 
    { 
     SelectedType = selectedType; 
     SelectedOption = selectedOption; 
     IsChecked = isChecked; 
    } 
} 

Я проверил, что SetChangedProperty запускается, но ничего не кажется, произошло после этого. Буду признателен, если кто-нибудь подскажет, почему.

ответ

1

Событие PropertyChanged инициируется, когда имущество действительно изменилось. Ваш список не изменяется, а только его содержимое, поэтому свойство с самим списком по-прежнему относится к одному и тому же объекту (списку).

Вы используете ObservableCollection, что и есть путь. Дело в том, что вы должны подписаться на событие CollectionChanged в вашем рендерере.

Кроме того, было бы проще использовать значение по умолчанию ListView и просто создать собственный визуализатор для ячеек.

Смежные вопросы