在我的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
答案 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
...