在WPF应用程序中,我有来自自定义控件的对象:
...
<MyNamespace:MyCustControl x:Name="x4y3" />
<MyNamespace:MyCustControl x:Name="x4y4" />
...
我可以使用名称来引用这些对象:
x4y4.IsSelected = true;
此功能也很有效:
public void StControls(MyCustControl sname)
{
...
sname.IsSelected = true;
...
}
....
StControls(x4y3);
但我想在调用此方法时使用字符串来引用对象。像这样(但这不起作用):
MyCustControl sc = new MyCustControl();
string strSc = "x1y10";
sc.Name = strSc;
StControls(sc); // nothing's happening
这种方式甚至无法编译:
MyCustControl sc = new MyCustControl();
string strSc = "x1y10";
sc = (MyCustControl) strSc; // Cannot convert type string to MyCustControl
StControls(sc);
如何使用string
变量来操纵对象(即将其转换为对象)?
答案 0 :(得分:9)
使用FindName
: -
MyCustControl sc = (MyCustControl)this.FindName("x1y10");
当您在XAML中使用x:Name时,将在与cs后面的代码中的类匹配的分部类中创建具有指定名称的字段。这个partial类是找到InitialiseComponent的实现的地方。在执行此方法期间,找到具有该名称的对象并将其分配给该字段,FindName用于执行此操作。
如果您的字符串包含这样的名称,您可以自己简单地调用FindName
,然后将返回的对象强制转换为自定义控件类型。
答案 1 :(得分:5)
这实际上并不是在施法。您需要按名称查找控件的对象引用,可以这样做:
MyCustControl control = (MyCustControl)frameworkElement.FindName("x4y3");
其中frameworkElement
是包含窗口(或任何面板,如网格)。从窗口后面的代码中,使用this
应该可以工作:)
如果您计划动态创建控件,请参阅this question,您的命名方案似乎建议我这样做。但是,如果是这种情况,FindName
根本不是必需的。您只需在创建二维数组时将对所有创建的控件的引用存储起来。
int[,] controls = new int[10, 10];
for (int x = 0; x < 10; x++)
{
for (int y = 0; y < 10; y++)
{
// Create new control and initialize it by whatever means
MyCustControl control = new MyCustControl();
// Add new control to the container
Children.Add(control);
// Store control reference in the array
controls[x, y] = control;
}
}
然后,您可以像这样访问控件:
controls[4, 3].IsSelected = true;