1

在 Windows 7 手机(Silverlight 平台)中,当创建一个 ListBox 时,该 ListBox 的名称被实例化并分配给一个同名的变量:

<ListBox Name="abcFeed" ...

并用作:

abcFeed.ItemsSource = feed.Items;

在我的应用程序中,我有许多提要,并希望将它们分配给各自的列表框。我在字符串字典中有列表框的名称。

this.feeds["abcFeed"] = "http://feed.abc.com/....";
this.feeds["nbcFeed"] = "http://feed.nbc.com/....";

但除了使用开关将提要分配给 ListBoxes 之外,我还想从字典中获取 ListBox 字符串名称并在循环中动态调用实例。

例如,而不是这样做:

feedName = "nbcFeed";
// Bind the list of SyndicationItems to our ListBox.
switch (feedName)
{
  case "abcFeed":
    abcFeed.ItemsSource = feed.Items;
    break;
  case "nbcFeed":
    nbcFeed.ItemsSource = feed.Items;
    break;
}

我想以某种方式获取字典键并调用实例化的变量名,例如:

feedName = "nbcFeed";
// nbcFeed.ItemsSource = feed.Items;
((ListBox) feedName).ItemsSource = feed.Items;

我已经研究过 Reflection、Assembly 和 Activator.CreateInstance() (虽然我已经有了实例),但我没有清楚地了解这是否可能。

可以这样做还是我被开关卡住了?

我也试过:

this.GetType().GetProperty(feedName).ItemsSource = feed.Items;

但我收到一个错误:

无法将 lambda 表达式转换为类型“System.Delegate”,因为它不是委托类型

4

2 回答 2

2

不幸的是,您不能使用反射访问在 XAML 中定义的字段。Silverlight 中的安全限制阻止访问 NonPublic 字段(例如为 XAML 元素生成的字段)。

使用 FindName 应该可以正常工作。

ListBox abcFeed = LayoutRoot.FindName("abcFeed") as ListBox;
于 2012-07-31T06:55:57.590 回答
1

是的,Reflection您需要这样做。但是这个:

this.GetType().GetProperty(feedName).ItemsSource = feed.Items;

不起作用,因为Type.GetProperty()方法返回 a PropertyInfo(作为Type.GetMethod()返回MethodInfo等等......)所以如果你想处理属性值,你应该使用PropertyInfo.GetValue()or方法。PropertyInfo.SetValue()

在您的情况下,这可能有效:

var myProperty = (ItemsControl)GetType().GetProperty(feedName).GetValue(this, null); 
myProperty.ItemsSource = feed.Items;
于 2012-07-31T06:20:13.377 回答