C# Xamarin渲染器不响应更改的属性

C# Xamarin渲染器不响应更改的属性,c#,mvvm,xamarin,xamarin.forms,C#,Mvvm,Xamarin,Xamarin.forms,我对自定义渲染器有一些问题。我的示例基于Xamarin官方网站的示例,但我无法获取渲染器中的OnElementPropertyChanged方法,在向绑定列表添加项目时未触发该方法 单元格: 渲染器 [assembly: ExportRenderer(typeof(MyNativeListView), typeof(Blabla.iOS.NativeiOSListViewRenderer))] namespace Blabla.iOS { public class NativeiOSLi

我对自定义渲染器有一些问题。我的示例基于Xamarin官方网站的示例,但我无法获取渲染器中的OnElementPropertyChanged方法,在向绑定列表添加项目时未触发该方法

单元格:

渲染器

[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);
            }
        }
    }
}
视图模型

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

}

我已经验证了SetChangedProperty已被触发,但此后似乎什么也没有发生。如果有人知道原因,我将不胜感激。

当属性确实发生更改时,会触发
PropertyChanged
事件。列表不会更改,只会更改其内容,因此列表本身的属性仍然引用同一对象(列表)

您正在使用一个
可观察的集合
,这是一个好方法。问题是您必须在渲染器中订阅
CollectionChanged
事件


此外,使用默认的
列表视图
并为单元格创建自定义呈现程序可能更容易。

当属性确实发生更改时,会触发
属性更改
事件。列表不会更改,只会更改其内容,因此列表本身的属性仍然引用同一对象(列表)

您正在使用一个
可观察的集合
,这是一个好方法。问题是您必须在渲染器中订阅
CollectionChanged
事件

此外,使用默认的
ListView
并为单元格创建自定义渲染器可能更容易

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

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