在自定义呈现程序中多次执行Xamarin.Forms OnPropertyChanged
我曾经遇到过这样一个问题:OnPropertyChanged处理程序在cutom渲染器中为同一个属性执行了多次。我创建了一个示例项目来重现这个问题。 我有以下表格和TableView:在自定义呈现程序中多次执行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
<?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