2010-04-01 29 views
5

Làm cách nào tôi có thể có hộp thoại để chỉnh sửa các thuộc tính của lớp có ràng buộc và có OK-Hủy trong hộp thoại?Chỉnh sửa hộp thoại, với các ràng buộc và OK/Hủy trong WPF

ý tưởng đầu tiên của tôi là thế này:

public partial class EditServerDialog : Window { 
    private NewsServer _newsServer; 

    public EditServerDialog(NewsServer newsServer) { 
     InitializeComponent(); 

     this.DataContext = (_newsServer = newsServer).Clone(); 
    } 

    private void ButtonClick(object sender, RoutedEventArgs e) 
    { 
     switch (((Button)e.OriginalSource).Content.ToString()) { 
      case "OK": 
       _newsServer = (NewsServer)this.DataContext; 
       this.Close(); 
       break; 
      case "Cancel": 
       this.Close(); 
       break; 
     } 
    } 
} 

Khi công tắc, trường hợp "OK", DataContext chứa các thông tin chính xác, nhưng trường hợp NewsServer thông qua ban đầu không thay đổi.

+0

Điều này có thể hữu ích nếu bạn hiển thị thiết lập ràng buộc. –

+0

Ví dụ về ràng buộc: {Ràng buộc NeedAuthentication, UpdateSourceTrigger = LostFocus, Mode = TwoWay}. Ràng buộc là chính xác vì this.DataContext chứa dữ liệu chính xác. – ErikTJ

Trả lời

1

Ví dụ ban đầu của đối tượng NewsServer của bạn không thay đổi vì bạn chưa thực sự sửa đổi nó. Sau khi xây dựng của bạn được gọi là bạn có ba NewsServer tài liệu tham khảo sau đây:

newsServer = original instance 
_newsServer = original instance 
DataContext = clone of original instance 

Sau khi nút OK được nhấp tài liệu tham khảo sẽ như sau:

newsServer = original instance 
_newsServer = clone of original instance (possibly modified) 
DataContext = clone of original instance (possibly modified) 

Hãy nhớ rằng đối tượng là các loại tài liệu tham khảo, bài tập của bạn đến _newsServer bạn chỉ cập nhật tham chiếu của nó chứ không phải giá trị của đối tượng.

Để cho phép tự cập nhật đối tượng NewsServer, có hai tùy chọn cho bạn biết, các tùy chọn khác có thể tồn tại, tùy chọn đầu tiên có lẽ là đơn giản nhất.

  • Thực hiện một phương pháp void Update(NewsServer source) trên đối tượng NewsServer của bạn sau đó thay vì thực hiện nhiệm vụ mới đến lĩnh vực _newsServer thay vì gọi phương thức cập nhật vào nó và vượt qua trong các giá trị DataContext tham khảo.
  • Hiển thị giá trị _newsServer với thuộc tính công khai/nội bộ. Bạn có thể tận dụng điều này thông qua một loạt các cơ chế: trả lời rõ ràng cho một sự kiện được nâng lên khi giá trị thuộc tính thay đổi; liên kết với thuộc tính (ví dụ: biến thuộc tính phụ thuộc hoặc triển khai INotifyPropertyChanged); hoặc chỉ mong đợi người gọi truy lục giá trị nếu và khi phương thức ShowDialog() trả về với giá trị là true.

Lưu ý rằng nếu bạn đẩy một chút logic trở lại người gọi, lớp hộp thoại của bạn có thể đơn giản hơn. Cụ thể, một cách tiếp cận là chỉ chỉ duy trì đối tượng được nhân bản, được hiển thị với người gọi qua thuộc tính (ví dụ: loại bỏ trường _newsServer hoàn toàn và chỉ sử dụng DataContext). Đối tượng này sẽ bị ràng buộc với các phần tử của hộp thoại như trước đây. Người gọi sẽ chỉ truy xuất tham chiếu của cá thể này trên kết quả true từ phương thức ShowDialog().

Ví dụ:

NewsServer newsServer = ...; 
EditServerDialog editServerDialog = new EditServerDialog(newsServer); 

if (editServerDialog.ShowDialog() == true) 
{ 
    newsServer = editServerDialog.DataContext; 
} 

Đối tượng nhân bản sẽ chỉ đơn giản là bỏ qua bởi người gọi nếu hộp thoại bị hủy bỏ, và do đó các phương pháp ShowDialog() trả false. Bạn chỉ có thể sử dụng lại thuộc tính DataContext như được hiển thị ở trên hoặc bạn có thể tạo thuộc tính khác (ví dụ: NewsServer), chỉ trả về giá trị thuộc tính DataContext (tức là làm cho mã rõ ràng hơn đối với giao diện công khai của lớp hộp thoại).

+0

Tôi nên làm như thế nào và vẫn có thể hủy và/hoặc áp dụng? – ErikTJ

3

Câu hỏi cũ nhưng tôi sẽ trả lời câu hỏi này cho người đọc trong tương lai ...

Bạn phải đặt UpdateSourceTrigger="Explicit" trên các kết buộc của mình để chúng không cập nhật nguồn thực cho đến khi người dùng nhấp OK. Sau đó, trên handler nút OK, bạn có thể viết:

BindingExpression be = MyTextBox.GetBindingExpression(TextBox.TextProperty); 
if (be!=null) be.UpdateSource(); 

Ngoài ra nếu bạn muốn thiết lập lại cam kết ràng buộc sử dụng đầu tiên nhà nước

BindingExpression be = MyTextBox.GetBindingExpression(TextBox.TextProperty); 
if (be!=null) be.UpdateTarget(); 

Nếu thoại của bạn rất phức tạp, bạn có thể muốn đi bộ tất cả các điều khiển nó một cách đệ quy .

0

Đây là một câu hỏi cũ, nhưng gần đây tôi đã gặp phải vấn đề này và thấy rằng có cách tốt hơn để xử lý nó với .NET 4.5.

Đầu tiên, đánh dấu cam kết ràng buộc của bạn UpdateSourceTrigger như Explicit:

<CheckBox IsChecked="{Binding MyProperty, UpdateSourceTrigger=Explicit}"/> 

Sau đó, trong xử lý sự kiện nhấn nút Ok bạn sử dụng này:

foreach (var be in BindingOperations.GetSourceUpdatingBindings(this)) 
{ 
    be.UpdateSource(); 
} 

GetSourceUpdatingBindings là một phương pháp mới trong .NET 4.5.

Nút hủy không cần phải làm bất cứ điều gì, vì các ràng buộc đã được đánh dấu là Rõ ràng và sẽ chỉ được "cam kết" khi UpdateSource được gọi.

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