在自定义呈现程序中多次执行Xamarin.Forms OnPropertyChanged

在自定义呈现程序中多次执行Xamarin.Forms OnPropertyChanged,xamarin.forms,Xamarin.forms,我曾经遇到过这样一个问题:OnPropertyChanged处理程序在cutom渲染器中为同一个属性执行了多次。我创建了一个示例项目来重现这个问题。 我有以下表格和TableView: <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.micr

我曾经遇到过这样一个问题:OnPropertyChanged处理程序在cutom渲染器中为同一个属性执行了多次。我创建了一个示例项目来重现这个问题。 我有以下表格和TableView:

<?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:local="clr-namespace:IssueWithEvents"
                 xmlns:components="clr-namespace:IssueWithEvents.Components;assembly=IssueWithEvents"
                 x:Class="IssueWithEvents.MainPage">
      <TableView Intent="Form" HasUnevenRows="True">
        <TableRoot>
          <TableSection Title="Sample Form">
            <EntryCell Label="Item 1"></EntryCell>
            <EntryCell Label="Item 2"></EntryCell>
            <ViewCell>
              <StackLayout Orientation="Horizontal">
                <Label Text="Item 3"/>
                <components:CustomEntry x:Name="MyEntry" HorizontalOptions="FillAndExpand" Text="{Binding Counter}"></components:CustomEntry>
                <Button Text="Push" Clicked="Button_OnClicked"></Button>
              </StackLayout>
            </ViewCell>
            <EntryCell Label="Item 4"></EntryCell>
            <EntryCell Label="Item 5"></EntryCell>
            <EntryCell Label="Item 6"></EntryCell>
            <EntryCell Label="Item 7"></EntryCell>
            <EntryCell Label="Item 8"></EntryCell>
            <EntryCell Label="Item 9"></EntryCell>
            <EntryCell Label="Item 10"></EntryCell>
            <EntryCell Label="Item 11"></EntryCell>
            <EntryCell Label="Item 12"></EntryCell>
            <EntryCell Label="Item 13"></EntryCell>
            <EntryCell Label="Item 14"></EntryCell>
            <EntryCell Label="Item 15"></EntryCell>
            <EntryCell Label="Item 16"></EntryCell>
            <EntryCell Label="Item 17"></EntryCell>
            <EntryCell Label="Item 18"></EntryCell>
          </TableSection>
        </TableRoot>
      </TableView>
    </ContentPage>
其中一个单元具有自定义布局,其中包含自定义组件。CustomEntry组件只是从Entry派生的简单组件,具有一个附加属性:

using Xamarin.Forms;

namespace IssueWithEvents.Components
{
    public class CustomEntry:Entry
    {

        private string _sampleProperty;

        public string SampleProperty
        {
            get { return _sampleProperty; }
            set
            {
                _sampleProperty = value;
                OnPropertyChanged();
            }
        }
    }
}
以下是渲染器:

using System.ComponentModel;
using IssueWithEvents.Components;
using IssueWithEvents.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace IssueWithEvents.Droid.Renderers
{
    public class CustomEntryRenderer:EntryRenderer
    {
        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            if (e.PropertyName == "SampleProperty")
            {
                System.Diagnostics.Debug.WriteLine("SampleProperty Changed");
            }
        }
    }
}
运行并按下按钮后,调试中的输出正常:

[0:] Button clicked
[0:] SampleProperty Changed
然后,如果我滚动列表,使自定义单元格消失,然后将其向后滚动并按下按钮,则输出如下:

[0:] Button clicked
[0:] SampleProperty Changed
[0:] SampleProperty Changed
每次从屏幕中滚动自定义单元格,然后将其向后滚动时,事件处理程序的执行次数都会增加:

[0:] Button clicked
[0:] SampleProperty Changed
[0:] SampleProperty Changed
[0:] SampleProperty Changed
[0:] SampleProperty Changed
[0:] SampleProperty Changed
我花了几天时间试图找到这个问题的解决方案,但没有成功。 我可以发现,用于单元重用的代码没有正确地处理以前的单元内容,也没有取消订阅onPropertyChanged事件。 所以它看起来像一个bug,但也许我做错了什么,或者有人知道如何解决这个问题


谢谢大家!

您是否可以尝试将
BindableProperty
用于
SampleProperty
。实际上,“OnElementPropertyChanged”对所有属性调用了多次,而不仅仅是自定义属性。我在处理程序中更改了少量代码以记录所有属性并获得以下输出:
[0:]OnChangedCalled for Renderer[0:]OnChangedCalled for Renderer[0:]单击了[0:]OnChangedCalled for Text[0:]OnChangedCalled for Text[0:]OnChangedCalled for SamplePropertyProperty[0:]OnChangedCalled for SamplePropertyProperty
您是否先尝试不使用自定义渲染器?CustomEntry的OnPropertyChanged会发生什么情况?您是否可以尝试将
BindableProperty
用于
SampleProperty
?刚刚检查-相同的问题。实际上,“OnElementPropertyChanged”对所有属性调用了多次,而不仅仅是自定义属性。我在处理程序中更改了少量代码以记录所有属性并获得以下输出:
[0:]OnChangedCalled for Renderer[0:]OnChangedCalled for Renderer[0:]单击了[0:]OnChangedCalled for Text[0:]OnChangedCalled for Text[0:]OnChangedCalled for SamplePropertyProperty[0:]OnChangedCalled for SamplePropertyProperty
您是否先尝试不使用自定义渲染器?CustomEntry的OnPropertyChanged会发生什么情况?
[0:] Button clicked
[0:] SampleProperty Changed
[0:] SampleProperty Changed
[0:] SampleProperty Changed
[0:] SampleProperty Changed
[0:] SampleProperty Changed