2010-08-25 62 views
0

從我的Silverlight/F#應用程序斷開連接後,我重新啓動並遇到了一個問題,我似乎無法解決問題。我有一個我的usercontrol的成員變量,它是一個列表ref,在按鈕單擊我想向它添加記錄 - 但它永遠不會更新。我非常肯定它與成爲會員有關,但我還沒有弄明白。會員列表ref未更新

在此先感謝那些花時間查看和回覆的人。

問題行:

. 
. 
. 
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]*\[email protected]\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 

回答

3

member this.brokers = ref List.Empty 

限定性吸氣劑。每次觸摸.brokers時,它都會重新運行右側的代碼。這是問題。

的修復程序是定義一個實例變量,並且返回的是:

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

然後,當被構造一個類的實例的單個ref被分配,並且你保持訪問經由相同ref對象成員財產。

+0

好的帽子不是我想要的!已經做出了改變,謝謝 – akaphenom 2010-08-25 22:17:05

3

Brian已經解釋了這個問題。然而,你有沒有任何理由不使用可變成員(使用getter和setter),而是使用返回參考單元的只讀成員?

使用GET /集成員會更地道的解決方案:

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 ...

+0

我真的對成員修飾符過度激動。我實際上並不需要這些成爲公共成員,只是私人實例。雖然可能應該是可變的,而不是ref。 – akaphenom 2010-08-26 13:30:07