升级Xamarin.Forms遇CS0542错误,求兼容FindByName的解决方案
我来帮你搞定这个升级后遇到的头疼问题!先理清楚根源,再给几个不用纠结的解决方案。
问题到底出在哪?
从Xamarin.Forms 3.0升级到3.5.0时,XAML编译工具的逻辑发生了变化:当页面XAML里设置的x:Name和页面类名(比如你的LocationsView)完全相同时,自动生成的xaml.g.cs文件会创建一个与类名同名的私有字段。这直接违反了C#的语法规则——成员名称不能与其封闭类型名称重复,于是就触发了CS0542错误。
你说的两难情况确实存在:改x:Name的话,自动生成的FindByName会用新名字,老代码里的引用就失效;不改的话,编译错误过不去。别慌,下面的方案能帮你跳出这个循环。
兼容解决方案(无需大规模修改代码)
方案1:移除XAML里的x:Name,用自身引用代替
其实那个自动生成的LocationsView字段本质上就是指向当前页面实例,完全没必要单独定义。我们可以直接去掉x:Name,然后调整相关引用:
- 修改XAML:删掉
x:Name="LocationsView"属性<!-- 修改前 --> <UserControls:RootPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Driessen.MijnDriessen.Views.DriessenLocationsView" xmlns:Behaviors="clr-namespace:Xam.Behaviors;assembly=Xam.Behaviors" xmlns:UserControls="clr-namespace:MyApp.Views.UserControls;assembly=MyApp" xmlns:Views="clr-namespace:MyApp.Views;assembly=MyApp" xmlns:AppFramework="clr-namespace:AppFramework;assembly=AppFramework" x:Name="LocationsView" AutomationId="LocationsView" Title="Locaties"> <!-- 修改后 --> <UserControls:RootPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Driessen.MijnDriessen.Views.DriessenLocationsView" xmlns:Behaviors="clr-namespace:Xam.Behaviors;assembly=Xam.Behaviors" xmlns:UserControls="clr-namespace:MyApp.Views.UserControls;assembly=MyApp" xmlns:Views="clr-namespace:MyApp.Views;assembly=MyApp" xmlns:AppFramework="clr-namespace:AppFramework;assembly=AppFramework" AutomationId="LocationsView" Title="Locaties"> - 调整XAML里的引用:如果之前有用
{x:Reference LocationsView}指向当前页面的地方,换成{RelativeSource Self}即可,比如:<!-- 修改前:绑定当前页面的属性 --> <Label Text="{Binding SomePageProperty, Source={x:Reference LocationsView}}" /> <!-- 修改后 --> <Label Text="{Binding SomePageProperty, Source={RelativeSource Self}}" /> - 调整代码里的引用:如果业务代码里有写
this.LocationsView的地方,直接改成this就好,因为两者完全是同一个实例。
这么改完之后,xaml.g.cs里不会再生成那个坑爹的同名字段,错误直接消失,也不用管FindByName的问题了——因为我们根本不再依赖它查找这个名称。
方案2:修改x:Name并同步更新所有引用
如果你确实需要保留x:Name,那就把它改成和类名不一样的名字(比如LocationsRootPage),然后同步更新所有用到这个名称的地方:
- 修改XAML的
x:Name:<UserControls:RootPage ... x:Name="LocationsRootPage" AutomationId="LocationsView" Title="Locaties"> - 全量替换引用:不管是XAML里的
{x:Reference},还是代码里的FindByName或者直接引用,都换成新的LocationsRootPage。
这时候自动生成的xaml.g.cs会用新名字创建字段,FindByName也会匹配新名称,不会出现失效的问题,同时也避开了CS0542错误。
方案3:升级到更高版本的Xamarin.Forms
这个问题在Xamarin.Forms 3.6及以后的版本里已经被官方修复了——编译工具会自动避免生成和类名同名的字段。如果你的项目没有强依赖3.5.0的特性,直接升级到更高的稳定版本,这是最省心的办法。
最后验证一下
改完之后记得先清理项目(Clean Solution),再重新编译(Rebuild Solution),看看CS0542错误是不是消失了,同时跑一下页面,确认功能都正常就行。
内容的提问来源于stack exchange,提问作者R.hagens

