2010-10-11 20 views
5

Trong ứng dụng WPF của tôi, tôi có một TextBox nơi người dùng có thể nhập một tỷ lệ phần trăm (như int, từ 1 đến 100). Thuộc tính Text là databound đến một thuộc tính trong ViewModel, trong đó tôi ép buộc giá trị nằm trong phạm vi cho trước trong setter.Coerce một WPF TextBox không hoạt động nữa trong .NET 4.0

Tuy nhiên, trong .NET 3.5, dữ liệu không được hiển thị đúng trong giao diện người dùng sau khi bị ép buộc. Trong this post on MSDN, Tiến sĩ WPF nói rằng bạn phải tự cập nhật các ràng buộc để chính xác sẽ được hiển thị. Do đó, tôi có trình xử lý TextChanged (trong Chế độ xem) gọi UpdateTarget(). Trong mã:

Xem XAML:

<TextBox Text="{Binding Percentage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static sys:String.Empty}}" 
    TextChanged="TextBox_TextChanged"/> 

Xem codebehind:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e) 
{ 
    // Removed safe casts and null checks 
    ((TextBox)sender).GetBindingExpression(TextBox.TextProperty).UpdateTarget(); 
} 

ViewModel:

private int? percentage; 
public int? Percentage 
{ 
    get 
    { 
     return this.percentage; 
    } 

    set 
    { 
     if (this.Percentage == value) 
     { 
      return; 
     } 

     // Unset = 1 
     this.percentage = value ?? 1; 

     // Coerce to be between 1 and 100. 
     // Using the TextBox, a user may attempt setting a larger or smaller value. 
     if (this.Percentage < 1) 
     { 
      this.percentage = 1; 
     } 
     else if (this.Percentage > 100) 
     { 
      this.percentage = 100; 
     } 
     this.NotifyPropertyChanged("Percentage"); 
    } 
} 

Thật không may, mã này phá vỡ trong .NET 4.0 (cùng mã, đơn giản đã thay đổi TargetFramework thành 4.0). Cụ thể, sau khi tôi ép buộc giá trị lần đầu tiên, TextBox bỏ qua bất kỳ giá trị ép buộc nào khác miễn là tôi tiếp tục nhập các giá trị số nguyên (vì tôi ràng buộc với một int).

Vì vậy, nếu tôi nhập "123", sau 3 tôi thấy giá trị "100". Bây giờ nếu tôi nhập "4", setter trong ViewModel nhận được giá trị "1004", nó coerces đến 100. Sự kiện TextChanged sau đó cháy (và TextBox.Text của người gửi là "100"!), Nhưng TextBox cho thấy " 1004 ". Nếu sau đó tôi nhập "5", trình thiết lập sẽ nhận giá trị "10045", v.v.

Nếu sau đó tôi nhập "a", đột nhiên Hộp văn bản hiển thị giá trị chính xác, tức là "100". Điều tương tự cũng xảy ra nếu tôi tiếp tục nhập số cho đến khi tràn int.

Làm cách nào để khắc phục sự cố này?

Trả lời

3

Hãy thử sử dụng trong XAML Explicit thay vì PropertyChanged:

<TextBox Text="{Binding Percentage, Mode=TwoWay, UpdateSourceTrigger=Explicit, TargetNullValue={x:Static System:String.Empty}}" 
      TextChanged="TextBox_TextChanged" /> 

và trong mã đằng sau UpdateSource thay vì UpdateTarget

private void TextBox_TextChanged(object sender, TextChangedEventArgs e) 
    { 
     // Removed safe casts and null checks 
     ((TextBox)sender).GetBindingExpression(TextBox.TextProperty).UpdateSource(); 
    } 

Tested nó và nó hoạt động. Btw vấn đề này có thể sẽ được giải quyết trong phiên bản sau của .NET.

0

Bạn có thể sử dụng PropertyChanged. Tuy nhiên, hãy thử ràng buộc với sự phụ thuộc EditValueProperty thay vì sự phụ thuộc TextProperty (hoặc các sự kiện). Nó sẽ hoạt động như mong muốn.

Các vấn đề liên quan