我正在尝试向标签添加名称,以便我可以使用 Content.FindByName<>() 方法找到它
据我所知,Xamarin.Forms.Label() 类没有 Name 属性
这是我的页面类
public class HelloWordCodePage : ContentPage
{
public Label HelloWorldLabel;
public HelloWordCodePage()
{
HelloWorldLabel = new Label{Text = "Hello World", };
ConstructView();
}
public void ConstructView()
{
Content = new StackLayout
{
Children =
{
HelloWorldLabel
}
};
}
}
如果您在 Xaml 中定义标签,则可以使用以下语法:
<Label x:Name="YourLableName" Text="A simple Label" />
然后像这样在后面的代码中访问它
YourLableName.Text = "bla bla"
但是,如果您不使用 Xaml,并且所有页面定义都在后面的代码中找到,您应该保留对该标签的引用以便访问它,而不是像 @Sten Petrov 评论的那样使用
Content.FindByName<>()
来查找它
我相信该名称仅在 XAML 中创建元素时使用。如果您查看继承,您会发现底部有 Element,它显式实现了 INameScope。您不能将 Label 强制转换为 INameScope,因为这是一个内部接口:
namespace Xamarin.Forms
{
internal interface INameScope
{
object FindByName(string name);
void RegisterName(string name, object scopedElement);
void UnregisterName(string name);
}
}
名称在Render处理阶段分配。此时无需知道呈现的名称,因为您正在跨平台ContentPage上工作。
有一个 GUID,但就像你说的,没有 ID。在我看来,您永远不会希望在如此高级别的页面设计中为生成的控件获取特定于平台的 ID。如果您这样做,那么您可能需要创建一个特定于平台的PageRenderer?
当您开始编写 CustomRenderers 并创建特定于平台的控件时,如果您希望任何自定义控件特定于平台的实现,您可以分配 ID。
请记住,在当前的 ContentPage 上 - 您已经有一个 class-scoped 对象引用到名为 HelloWorldLabel 的标签,您可以在执行时使用它来更改其在页面上的外观等。
样式ID
使用 StyleId 属性来标识应用程序中的各个元素 用于在 ui 测试和主题引擎中进行识别。
正如 IdoT 所说,如果您在运行时定义一个对象,则需要保留对该对象的引用才能访问它,因为无法分配名称。 我使用这样的字典:
Dictionary<Guid, String> ControlsDictionary = new Dictionary<Guid, string>();
然后当我创建一个对象时:
Button bt = new Button {Text="Yay!"};
bt.Clicked += OnButtonClicked;
StackLayout.Children.Add(bt);
ControlsDictionary.Add(bt.Id, "myname");
在 Click 事件处理程序中,我可以识别发件人“名称”:
async void OnButtonClicked(object sender, EventArgs args)
{
Button btn = (Button)sender;
String NameofButton = ControlsDictionary[btn.Id];
}
您也可以从“名字”中获取Id:
Guid IdfromName = ControlsDictionary.First(x => x.Value == "myname").Key;
虽然有点晚了,但正在解决一些 xamarin 表单问题,并记得在开始实现 MVVM 之前,我过去做过一些类似的事情。这就是我使用的方式
Content.FindByName<>()
下面是一个粗略的例子。
XAML
<BoxView Color="Gray" HeightRequest="2" HorizontalOptions="Fill" />
<Label x:Name="DoorMaterial" x:Uid="41" Text="Door Material"/>
<RadioButton GroupName="Door_Material" x:Name="RB_99" Value="99" ClassId="41" CheckedChanged="RB_CheckedChanged" Content="Wood" ></RadioButton>
<RadioButton GroupName="Material" x:Name="RB_100" Value="100" ClassId="41" CheckedChanged="RB_CheckedChanged" Content="Steel" ></RadioButton>
<RadioButton GroupName="Material" x:Name="RB_101" Value="101" ClassId="41" CheckedChanged="RB_CheckedChanged" Content="Upvc" ></RadioButton>
<RadioButton GroupName="Material" x:Name="RB_102" Value="102" ClassId="41" CheckedChanged="RB_CheckedChanged" Content="Composite" ></RadioButton>
C#
private void SetPageFields(ICollection<DoorTemplateAnswerRecordModel> answerRecordModelsList)
{
string RadioButtonName = "RB_";
foreach (var answerRecordModel in answerRecordModelsList)
{
var answerId = answerRecordModel.AnswerId.ToString();
var combinedWithId = RadioButtonName + answerId;
var getCheckBox = Content.FindByName<RadioButton>(combinedWithId);
if (getCheckBox != null)
{
getCheckBox.IsChecked = true;
}
}
}