Список участников Ref не обновляется - PullRequest
0 голосов
/ 26 августа 2010

После перерыва в моем приложении 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 ]

3 голосов
/ 26 августа 2010

Брайан уже объяснил проблему.Однако есть ли причина, по которой вы не используете изменяемый элемент (с getter и setter) и вместо этого используете элемент readonly, который возвращает ссылку на ячейку?

Использование элемента 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 напрямую ...

3 голосов
/ 26 августа 2010

Это

member this.brokers = ref List.Empty

определяет получатель свойства. Каждый раз, когда вы нажимаете .brokers, он перезапускает код с правой стороны. Это проблема.

Исправление будет состоять в том, чтобы определить переменную экземпляра и вернуть это:

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

Затем при создании экземпляра класса выделяется один ref, и вы продолжаете обращаться к тому же объекту ref через свойство member.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...