成员列表ref不更新

时间:2010-08-25 22:12:54

标签: f# oop

在我的Silverlight / F#应用程序中断之后,我开始重新进入它并遇到一个我似乎无法理解的问题。我有一个我的usercontrol的成员变量,它是一个列表引用,按钮点击我想要添加记录 - 但它永远不会更新。我很确定它与成员有关,但我还没弄明白。

提前感谢那些花时间查看和回复的人。

问题行:

.
.
.
member this.brokers = ref List.empty
.
.
.
// this line doesn't seem to work
this.brokers := candidate :: (!this.brokers)
.
.
.

班级:

type Page() as this =    
    inherit UriUserControl("/xyz;component/page.xaml", "page")
    do
        this.firm.ItemsSource <- RpcXYZ.getFirms()
        this.email.Background <- SolidColorBrush(Colors.Red)
        this.addBtn.IsEnabled <- false
        ()

    // instance data
    member this.brokers = ref List.empty

    // bound controls for add candidate
    member this.FE : FrameworkElement = (this.Content :?> FrameworkElement)
    member this.fname : TextBox = this.FE ? fname
    member this.lname : TextBox = this.FE ? lname
    member this.email : TextBox = this.FE ? email
    member this.firm : RadComboBox = this.FE ? firms
    member this.addBtn : RadButton = this.FE ? addBtn

    member this.addCadidate_Click (sender : obj) (args : RoutedEventArgs)  = 
        let inline findFirm (f : RpcXYZ.firm) =
            f.id = Int32.Parse(this.firm.SelectedValue.ToString())

        let candidate : SalesRep = {
            id = -1 ; 
            fname =  this.fname.Text ;
            lname = this.lname.Text ;
            email = this.email.Text ;
            phone = "" ;
            firm = List.find findFirm <| RpcXYZ.getFirms();
            score = None ;
        }

        // this line is fine t is a list of 1 item after 1 click
        let t = candidate :: (!this.brokers)

        // this line doesn't seem to work
        this.brokers := candidate :: (!this.brokers)

        ChildWindow().Show()  |> ignore ;

    member this.email_Changed (o : obj) (arg : TextChangedEventArgs) = 
        let txtBox = (o :?> TextBox)
        let emailRegex = Regex("(\w[-._\w]*\w@\w[-._\w]*\w\.\w{2,3})")
        if emailRegex.IsMatch(txtBox.Text) = false then
            txtBox.Background <- SolidColorBrush(Colors.Red)
            this.addBtn.IsEnabled <- false
        else
            txtBox.Background <- new SolidColorBrush(Colors.White)
            this.addBtn.IsEnabled <- true

2 个答案:

答案 0 :(得分:3)

member this.brokers = ref List.Empty

定义属性getter。每次触摸.brokers,它都会重新运行右侧的代码。这就是问题所在。

修复方法是定义一个实例变量,然后返回:

let brokers = ref List.Empty
member this.Brokers = brokers

然后在构造类的实例时分配单个ref,并通过成员属性继续访问相同的ref对象。

答案 1 :(得分:3)

Brian已经解释了这个问题。但是,您是否有任何理由不使用可变成员(使用getter和setter)而是使用返回引用单元的只读成员?

使用get / set成员将是更惯用的解决方案:

let mutable brokers = List.Empty 

member this.Brokers 
  with get() = brokers
  and set(value) = brokers <- value

声明有点长(不幸的是,F#中没有自动属性!),但该成员看起来像一个标准属性(来自F#和C#)。然后你可以像这样使用它:

x.Brokers <- candidate :: x.Brokers

虽然,您只需要应该从该类型外部访问的公共成员的属性。对于私有字段,您可以直接使用可变值brokers ...