F#Silverlight 3.0自定义控件属性抛出:NullReferenceException

时间:2010-05-18 18:26:20

标签: silverlight silverlight-3.0 f# custom-controls

我已经用:

定义了一个Control
 static member ItemsProperty : DependencyProperty = 
        DependencyProperty.Register(
            "Items",
            typeof<MyMenuItemCollection>,
            typeof<MyMenu>,
            null);

 member this.Items
        with get () : MyMenuItemCollection = this.GetValue(MyMenu.ItemsProperty) :?> MyMenuItemCollection
        and set (value: MyMenuItemCollection) = this.SetValue(MyMenu.ItemsProperty, value);

访问时出现问题:

for menuItem in this.Items do
    let contentElement: FrameworkElement = menuItem.Content

我在this.Items上得到 null引用异常;

  

'Items'抛出了类型的异常   'System.NullReferenceException'

我在构造函数中初始化后立即:

do
    this.Items <- new CoolMenuItemCollection()

2 个答案:

答案 0 :(得分:1)

我认为问题在于F#中的static member与您可能预期的公共字段不对应,而是与get成员的属性对应。这意味着,每次访问this.ItemsProperty时,您实际上都在创建一个新的依赖项属性。

您可以创建一个这样的静态字段:

type Control = 
  // private static field
  static let itemsProperty : DependencyProperty =  
    DependencyProperty.Register
      ("Items", typeof<MyMenuItemCollection>, typeof<MyMenu>, null); 
  // public static property with getter 
  static member ItemsProperty = itemsProperty  

  // You can use both private 'itemsProperty' field or public property here
  member this.Items 
    with get () : MyMenuItemCollection = 
      this.GetValue(itemsProperty) :?> MyMenuItemCollection 
    and set (value: MyMenuItemCollection) = 
      this.SetValue(itemsProperty, value) 

答案 1 :(得分:0)

大部分框架都没有调用CLR getter。这是为了方便开发人员访问文件背后的代码。

如果需要,在构造函数内部将是初始化集合的好地方。

不要在空集合中设置默认值(上面的依赖项属性声明中为null)。默认值是一个共享的单个静态实例 - 因此控件的每个实例都会共享同一个列表,而不是您想要的那个。