2010-06-04 37 views
47

试图让我的头部绕过所有这些动态的东西。对不起,如果这个问题很愚蠢,没有经验在这个领域。只是在探索c#4时,将一个未知(在设计时间)的属性添加到ExpandoObject中。

如果我有一个ExpandoObject并希望在运行时向它添加公共属性(使用get和set),我该如何去做呢?

例如,我有一个documentTemplate和一个文档,它有一个指向documentTemplate的属性。这个文档模板有一些标签标题(例如在学生中开发的功能),这些标题在制作文档时应该加以说明(例如浓度,记忆等)。因此,只要在文档中设置了模板,我想要创建一个类,该模板具有与模板中标记标题相同名称的属性,然后使用某个UI元素(如PropertyGrid),我可以让用户根据标签标题填写标签值。

感谢您的阅读!

+4

只是想补充一点,我读了ExpandoObject上的这篇文章的死树版本:http://msdn.microsoft.com/en-us/magazine/ff796227.aspx不知道它是否回答你的问题,但它对我来说是一个伟大的胜利。 – Yoopergeek 2010-08-05 18:37:56

回答

92

我想知道有可能将成员添加到“对飞”的一类,并与该样品上来:

using System; 
using System.Collections.Generic; 
using System.Dynamic; 

class Program 
{ 
    static void Main() 
    { 
     dynamic expando = new ExpandoObject(); 
     var p = expando as IDictionary<String, object>; 

     p["A"] = "New val 1"; 
     p["B"] = "New val 2"; 

     Console.WriteLine(expando.A); 
     Console.WriteLine(expando.B); 
    } 
} 

此代码段的一点是,成员A和B被定义为通过ExpandoObject的IDictionary接口添加和添加的字符串文字(硬编码/字符串化)。我们通过直接访问它们并输出到控制台来测试密钥的存在和值(并验证概念)。

+0

无法将[]的索引用于'System.Dynamic.ExpandoObject'类型的表达式。有任何想法吗? – 2014-02-03 21:08:15

+0

@JasonFoglia:是的。请将其作为问题发布,并显示一些代码,包括输入和预期输出。我们只能猜测评论可能会发生什么...... – 2014-02-04 04:52:41

3

是的,ExpandoObject的设计非常强大,可以动态地将属性添加到“属性包”中。然而,不支持给予这样一个属性吸气剂和固定剂的概念。如果你仔细想一想,也许这很清楚:如果你已经知道吸气和吸气装置应该做什么,它就不再是一个动态属性了。您可以得到的最接近的是实现INotifyPropertyChanged事件,以便您可以检测到更改。一些示例代码:

using System; 
using System.Dynamic; 
using System.ComponentModel; 

class Program { 
    static void Main(string[] args) { 
    dynamic obj = new ExpandoObject(); 
    obj.test = 42;  // Add a property 
    Console.WriteLine(obj.test); 

    var inpc = (INotifyPropertyChanged)obj; 
    inpc.PropertyChanged += inpc_PropertyChanged; 
    obj.test = "foo"; 
    Console.ReadLine(); 
    } 

    static void inpc_PropertyChanged(object sender, PropertyChangedEventArgs e) { 
    Console.WriteLine("'{0}' property changed", e.PropertyName); 
    } 

} 
+0

感谢您的解释和编码Hans。 但是,我的查询稍有不同。我想知道是否可以在运行时添加“test”属性?我的意思是我们甚至不知道设计时的财产名称。类似于:obj.SetProperty(stringVariable)= anotherStringVariable。 – virtualmic 2010-06-04 17:23:49

+0

呃,没有。你为什么不简单地使用Dictionary ? – 2010-06-04 17:32:26

+0

因此,我可以轻松地绑定到Windows窗体UI – virtualmic 2010-06-05 03:15:11

4

这是可能的委托属性添加到ExpandoObject,然后采取行动(几乎)一样的方法。例如,

dynamic obj = new ExpandoObject(); 
obj.GetDocumentTemplate =() => { ... }; 
... 
obj.GetDocumentTemplate(); // invokes delegate 
2

我刚刚发现了这个有趣的事实:XAML绑定到ExpandoObject还会创建绑定试图访问的属性

我仍然需要更多的创造力来找出这可能是有益的。在UI上创建动态对象?听起来很酷:D我会尝试一些东西。