2016-09-02 4 views
0

사용자 지정 렌더러에 문제가 있습니다. 내 샘플은 공식 Xamarin 사이트의 샘플을 기반으로하지만 바인딩 된 목록에 항목을 추가 할 때 렌더러에서 OnElementPropertyChanged 메서드가 트리거되지 않습니다.Xamarin Renderer가 변경된 속성에 응답하지 않습니다.

셀 :

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); 

    } 

} 

렌더러

[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; 
    } 
} 

뷰 모델

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을 사용하고 셀에 대한 사용자 지정 렌더러를 만드는 것이 더 쉽습니다.

관련 문제