2010-04-14 30 views
26

Tôi đã có một hộp thoại WPF đơn giản với hai kiểm soát này:WPF MVVM: TextBox và Button mặc định ràng buộc thực hiện cập nhật quá muộn

<TextBox Text="{Binding MyText}"/> 
<Button Command="{Binding MyCommand}" IsDefault="True"/> 

Bây giờ, khi tôi nhập một số văn bản trong TextBox và nhấp vào nút sử dụng chuột, mọi thứ hoạt động như mong đợi: TextBox sẽ đặt MyText và MyCommand được gọi.

Nhưng khi tôi nhập một số văn bản và nhấn enter để "bấm" nút mặc định, nó không hoạt động. Kể từ khi nhấn vào tiêu điểm không rời khỏi TextBox, ràng buộc sẽ không làm mới MyText. Vì vậy, khi MyCommand được gọi (hoạt động), MyText sẽ chứa dữ liệu cũ.

Làm cách nào để khắc phục sự cố này trong MVVM? Trong mã cổ điển phía sau tôi có lẽ chỉ cần gọi "MyButton.Focus()" trong trình xử lý MyCommand, nhưng trong MVVM, trình xử lý MyCommand không biết gì về nút.

Vậy hiện tại là gì?

Trả lời

30

Thêm UpdateSourceTrigger vào hộp văn bản của bạn với giá trị PropertyChanged. Hành vi mặc định của Textbox là cập nhật nguồn, khi nó bị mất tiêu điểm.

<TextBox Text="{Binding MyText, UpdateSourceTrigger=PropertyChanged}"/> 
+2

Vì vậy, tôi cần phải thêm điều này vào mọi ràng buộc (vì luôn có các nút có thể truy cập phím tắt của tôi)? – Sam

2

Một giải pháp ist, để tạo lớp OKButton của riêng bạn gọi Me.Focus trong OnClick-Method. Điều này sẽ được gọi trước khi Click_Event và trước khi bất kỳ Lệnh nào được liên kết với nút. Bạn chỉ cần nhớ sử dụng OKButton thay vì thiết lập IsDefault = True

Public Class OKButton 
    Inherits System.Windows.Controls.Button 

    Public Sub New() 
    MyBase.New() 
    Me.Content = "OK" 
    Me.IsDefault = True 
    End Sub 

    Protected Overrides Sub OnClick() 
    Me.Focus() 
    MyBase.OnClick() 
    End Sub 
End Class 
+0

Điều gì về các nút không phải là nút mặc định và được kích hoạt bằng cách sử dụng phím tắt alt? Điều này sẽ không làm việc cho họ. – Sam

5

Hãy thử điều này. Mã này di chuyển tiêu điểm vào nút được nhấp. Do đó ràng buộc hoàn thành trước khi lệnh được xử lý.

public App() 
    { 
     EventManager.RegisterClassHandler(typeof(Button), Button.ClickEvent, new RoutedEventHandler(GenericButtonClickHandler)); 
    } 

    void GenericButtonClickHandler(object sender, RoutedEventArgs e) 
    { 
     var button = sender as Button; 
     if (button == null) 
      return; 
     if (button.IsDefault) 
      button.Focus(); 
    } 
+0

Điều gì về các nút không phải là nút mặc định và được kích hoạt bằng cách sử dụng phím tắt alt? Điều này sẽ không làm việc cho họ. – Sam

+0

Có, Sam. Bạn phải 'if (button.IsDefault)' không áp dụng cho giải pháp chung. – Aleks

+0

Nhưng ý tưởng của giải pháp này là nắm bắt tất cả các nhấp chuột trước khi xử lý và tập trung vào một nút ở một nơi. Nhưng không sử dụng 'UpdateSourceTrigger' trong mọi ứng dụng có thể chỉnh sửa được trong toàn bộ ứng dụng. – Aleks

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