忽略绑定初始化

2023-12-23

最初的问题来自于关于折线的个人项目Xamarin.Forms.Map https://github.com/Emixam23/XamarinByEmixam23/tree/master/Detailed%20Part/Controls/Map/MapPolylineProject其中初始化是通过 XAML 部分的绑定来实现的。

让我通过一个例子来清楚地说明:

我有一个对象自定义地图.cs继承自Xamarin.Forms.Map (该文件位于PCL部分->CustomControl/CustomMap.cs)

public class CustomMap : Map, INotifyPropertyChanged
{
    public static readonly BindableProperty PolylineAddressPointsProperty =
        BindableProperty.Create(nameof(PolylineAddressPoints), typeof(List<string>), typeof(CustomMap), null);
    public List<string> PolylineAddressPoints
    {
        get { return (List<string>)GetValue(PolylineAddressPointsProperty); }
        set
        {
            SetValue(PolylineAddressPointsProperty, value);
            this.GeneratePolylineCoordinatesInner();
        }
    }   
    // ...
}

正如您所看到的,我有一个带有评估器的可绑定属性,并且 XAML 似乎没有使用此评估器。

So the MainPge.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"
         xmlns:control="clr-namespace:MapPolylineProject.CustomControl;assembly=MapPolylineProject"
         x:Class="MapPolylineProject.Page.MainPage">

  <ContentPage.Content>
    <control:CustomMap x:Name="MapTest" PolylineAddressPoints="{Binding AddressPointList}"
                                       VerticalOptions="Fill" HorizontalOptions="Fill"/>

  </ContentPage.Content>

</ContentPage>

The MainPge.xaml.cs part:

public partial class MainPage : ContentPage
{
    public List<string> AddressPointList { get; set; }

    public MainPage()
    {
        base.BindingContext = this;

        AddressPointList = new List<string>()
        {
            "72230 Ruaudin, France",
            "72100 Le Mans, France",
            "77500 Chelles, France"
        };

        InitializeComponent();

        //MapTest.PolylineAddressPoints = AddressPointList;
    }
}

所以,如果我编辑,一切都很好PolylineAddressPoints从对象实例(如果评论的部分没有被评论..),但是如果我从 XAML 初始化值(从InitializeComponent();),它不起作用,SetValue, 在里面Set {}, 的CustomMap.PolylineAddressPoints, 不叫..

然后我在网上搜索了相关内容并得到了一些关于依赖属性?或类似的东西。所以我尝试了一些解决方案,但是,从WPF,所以一些方法,例如DependencyProperty.Register();。所以是的,我找不到解决问题的方法..

我也想过一些事情,如果DependencyProperty.Register();将存在于Xamarin.Forms,那么这意味着我必须对每个值都这样做?因为,如果每个值都必须由XAML 绑定逻辑,这是行不通的,我必须注册每个值,不是吗?

如果我不清楚,我很抱歉,但我对这个问题很迷茫。请随时询问更多详细信息,提前致谢!

最后,最初的问题是我试图从 XAML 设置对象/控件的值。通过绑定执行此操作不起作用,似乎它被忽略了。但是,如果我执行以下操作,它确实有效:

MapTest.PolylineAddressPoints = AddressPointList;  

这里面有多个疑问:

  • 为什么使用 Xaml 时从未调用属性设置器?
  • 我是否正确定义了 BindableProperty ?
  • 为什么我的绑定失败?

让我以不同的顺序回答它们。

我是否正确定义了 BindableProperty ?

BindableProperty 声明是正确的,但可以通过使用来改进IList<string>:

public static readonly BindableProperty PolylineAddressPointsProperty =
    BindableProperty.Create(nameof(PolylineAddressPoints), typeof(IList<string>), typeof(CustomMap), null);

但属性访问器是错误的,应该只包含以下内容:

public IList<string> PolylineAddressPoints
{
    get { return (IList<string>)GetValue(PolylineAddressPointsProperty); }
    set { SetValue(PolylineAddressPointsProperty, value); }
}

我会在回答下一个问题时告诉你原因。但您希望在属性更改时调用方法。为此,您必须引用propertyChanged委托给CreateBindableProperty, 像这样:

public static readonly BindableProperty PolylineAddressPointsProperty =
    BindableProperty.Create(nameof(PolylineAddressPoints), typeof(IList<string>), typeof(CustomMap), null,
                            propertyChanged: OnPolyLineAddressPointsPropertyChanged);

你也必须声明该方法:

static void OnPolyLineAddressPointsPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
    ((CustomMap)bindable).OnPolyLineAddressPointsPropertyChanged((IList<string>)oldValue, (IList<string>)newValue);
}

void OnPolyLineAddressPointsPropertyChanged(IList<string> oldValue, IList<string> newValue)
{
    GeneratePolylineCoordinatesInner();
}

为什么使用 Xaml 时从未调用属性设置器?

该属性和属性访问器仅在通过代码访问属性时才被调用。C# code.

当从 Xaml 设置具有 BindablePrperty 后备存储的属性时,属性访问器将被绕过并SetValue()是直接使用的。

当定义一个Binding,无论是从代码还是从 Xaml,属性访问器都再次被绕过并且SetValue()当需要修改属性时使用。什么时候SetValue()被调用时,propertyChanged委托在属性更改后执行(此处完成,propertyChanging被调用before属性变更)。

您可能想知道如果可绑定属性仅由 xaml 使用或在 Binding 上下文中使用,为什么还要定义该属性呢?好吧,我说过属性访问器没有被调用,但它们是在 Xaml 和 XamlC 的上下文中使用的:

  • a [TypeConverter]可以在属性上定义属性,并将使用
  • with XamlCon,属性签名可用于在编译时推断Type of the BindableProperty.

因此,始终为公共 BindableProperties 声明属性访问器是一个好习惯。总是。

为什么我的绑定失败?

当你使用CustomMapView and ViewModel(我不会告诉 Mvvm 警察),在构造函数中执行此操作应该足够了:

BindingContext = this; //no need to prefix it with base.

当你已经这样做时,你的Binding修改后应该可以工作BindableProperty以我之前解释的方式声明。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

忽略绑定初始化 的相关文章

随机推荐

  • NSDateFormatter 显示错误的年份

    我在 iOS 6 中使用 xcode 4 5 4G182 NSDateFormatter 在 iOS 6 中显示错误的年份 如何解决 NSDateFormatter dateFormatter NSDateFormatter alloc i
  • IE 中的 moz-border-radius,moz-box-shadow

    我正在使用 moz border radius webkit border top left radius 将圆角 div 添加到我的网站 这些在 Mozilla chrome 和 safari 中工作得很好 但像往常一样 Internet
  • 具有接口继承的 Winforms 数据绑定

    在我因为这个问题而更改应用程序的域之前 我需要有人确认我所看到的内容 问题是 当针对相互继承的接口进行数据绑定时 您无法看到基本接口上的属性 我正在开发一个使用数据绑定的 WinForms 应用程序 这是在 net3 5中 不 我不能使用w
  • 如何在命令行上提供非 Base 64 编码的密钥

    关于AWS S3工具 同步 和 客户提供的加密密钥 它说here http docs aws amazon com cli latest reference s3 sync html sse c key 字符串 客户提供的加密密钥 用于服务
  • History.pushState 之后前进按钮不起作用

    我已经找到了如何修复后退按钮 但前进按钮仍然无法修复 网址会更改 但页面不会重新加载 这就是我正在使用的 anchor wrapper css position relative slanted css top 0 Do something
  • PHP 错误:警告:无法修改标头信息 - [重复] 已发送标头

    这个问题在这里已经有答案了 您好 我正在用 PHP 编写一个简单的邮件脚本 我发现的每个人都说它可能是前面的空白 但正如你所看到的 我在我的代码中找不到类似互联网上解决方案的内容 错误说 输出从 customers e e 5 httpd
  • 运行时控制台中的核心数据信息和错误

    我在运行时在控制台中遇到了以下消息 我不知道为什么 我到处搜索过 似乎没有人遇到这个 信息 获取响应无法打开文件 Users userName Library Application Support iPhone Simulator 7 0
  • 如何在 C# 中生成唯一的文件名

    我已经实现了一种算法 将为保存在硬盘驱动器上的文件生成唯一的名称 我正在追加DateTime 小时 分钟 秒和毫秒但它仍然会生成重复的文件名 因为我一次上传多个文件 为要存储在硬盘驱动器上的文件生成唯一名称以便没有两个文件相同的最佳解决方案
  • powershell的并行foreach最多使用5个线程吗?

    The throttlelimit的参数foreach parallel可以控制执行脚本时使用多少个进程 但即使我设置了 我也不能有超过5个进程throttlelimit大于5 该脚本在多个 powershell 进程中执行 所以我检查脚本
  • 使用实体框架进行软删除(是历史列)

    我正在使用一个数据库 设计者决定用 IsHistorical 位列标记每个表 没有考虑正确的建模 并且我无法更改架构 在开发与导航属性交互的 CRUD 屏幕时 这会造成一些摩擦 我不能简单地获取一个产品 然后编辑它的 EntityColle
  • 使用 XMLHttpRequest Level 2 模拟文件表单提交

    在我当前的页面上 我使用带有输入元素的旧文件上传 然而 现在我已经从这个非常好的系列文章中实现了拖放 http www sitepoint com html5 file drag and drop http www sitepoint co
  • macOS Catalina 中禁用 SIP 的只读文件系统 [关闭]

    Closed 这个问题是与编程或软件开发无关 help closed questions 目前不接受答案 我正在尝试将一些文件从路径复制到我的库路径 usr lib 我正在尝试使用 sudo cp my file usr lib 我得到了这
  • 工具栏搜索建议主题

    我正在尝试将搜索建议更改为 浅色主题 我正在使用 appcompat v7 22 2 0 库并阅读有关新功能 https philio me styling the searchview with appcompat v21 用于自定义搜索
  • 猪拉丁法翻译

    尝试用 ruby 编写方法来翻译 pig latin 中的字符串 规则 规则 1 如果单词以元音开头 则在单词末尾添加 ay 音 规则2 如果单词以辅音开头 则将其移动到单词的末尾 然后在单词的末尾添加 ay 音 并且当单词以2个辅音开头时
  • Flink 中是否可以实现具有多个工作线程的全局状态?

    在 Flink 文档中 我到处都看到状态对于映射函数和工作线程来说是独立的 这在独立方法中似乎很强大 但是如果 Flink 在集群中运行怎么办 Flink 能否处理所有工作人员都可以添加数据并查询数据的全局状态 来自 Flink 关于状态的
  • 在 spring-boot 2.6.2 中,无法从类路径初始化 Logback 日志记录:logback-spring.groovy

    我将 spring boot 2 5 6 的 spring boot 应用程序迁移到 spring boot 2 6 2 但从那时起 启动告诉 java lang IllegalStateException 无法从类路径初始化 Logbac
  • 列出可供下载的文件 - 文件存储在仅应用程序可访问的位置

    我有一组 pdf 文件存储在只能由应用程序访问的位置 因此这些文件无法通过 http 直接访问 文件路径由数据库存储 当用户选择下载文件时 将执行以下代码 Response ContentType Application pdf Respo
  • 调试时无法查看变量值

    我正在尝试调试我正在处理的当前应用程序的部分 但是当我尝试检查属性 变量的值时 我收到错误 Cannot evaluate expression because a thread is stopped at a point where ga
  • Angular 5无法匹配延迟加载模块的命名出口上的任何路由[重复]

    这个问题在这里已经有答案了 我的根模块的路线是这样的 RouterModule forRoot path redirectTo management portal pathMatch full path management portal
  • 忽略绑定初始化

    最初的问题来自于关于折线的个人项目Xamarin Forms Map https github com Emixam23 XamarinByEmixam23 tree master Detailed 20Part Controls Map