2010-03-17 29 views
13

Khá đơn giản: Tôi đang tìm cách làm giống như this nhưng trong winforms. Tất cả những gì google dường như kéo lên là WPF cụ thể (. Tức là tôi không muốn tham khảo presentationframework.dll)ràng buộc một usercontrol đối diện với một thuộc tính bool

Giải thích nếu bạn không muốn đọc vào liên kết:

Sau đây là một đại diện cho ý định của những gì tôi muốn làm, mặc dù nó rõ ràng không hoạt động.

CheckBox1.DataBindings.Add(new Binding("Checked", this.object, "!SomeBool")); 

Trả lời

16

Bạn có hai lựa chọn:

  1. Tạo đối tượng Binding bằng tay và đính kèm vào FormatParse sự kiện và trao đổi các giá trị trong mỗi người.
  2. Tạo một tài sản bổ sung trên lớp mà chỉ đảo ngược logic của tài sản dự định

Tùy chọn đầu tiên là sạch, IMO, vì nó không buộc API của lớp học của bạn để làm theo thiết kế giao diện người dùng của bạn, mặc dù tùy chọn thứ hai là (nhẹ) dễ dàng hơn.

Ví dụ về Lựa chọn 1

private void SwitchBool(object sender, ConvertEventArgs e) 
{ 
    e.Value = !((bool)e.Value); 
} 

... 

Binding bind = new Binding("Checked", this.object, "SomeBool"); 

bind.Format += SwitchBool; 
bind.Parse += SwitchBool; 

CheckBox1.DataBindings.Add(bind); 

Ví dụ về Lựa chọn 2

public class SomeClass 
{ 
    public bool SomeBool { get; set; } 

    public bool NotSomeBool 
    { 
     get { return !SomeBool; } 
     set { SomeBool = !value; } 
    } 
} 

... 

CheckBox1.DataBindings.Add("Checked", this.object, "NotSomeBool"); 

lần nữa, tôi rất ủng hộ phương án 1, vì phương án 2 yêu cầu bạn chỉnh lớp học của bạn để bạn Thiết kế giao diện người dùng.

+0

+1 Tôi thích tùy chọn đầu tiên của bạn, không biết :-) – Javier

+0

Tôi đã biết tùy chọn 2 và có lẽ tôi đã đề cập rằng tôi không muốn đặt giao diện người dùng trong mô hình miền của mình, đó là lý do tôi đã không đi với nó. Điều đó nói rằng, tôi đã thực hiện tùy chọn đầu tiên thành công. Cảm ơn nhiều. Tôi muốn chỉ ra cho bất cứ ai có thể thấy điều này trong tương lai: Bạn không thể thêm ràng buộc đó vào nhiều điều khiển, người ta phải tạo ra một điều khiển giao diện người dùng (Đó là điều tôi muốn làm). –

+1

+1 cho tùy chọn đầu tiên, tôi đã cố gắng để giải quyết điều tương tự. Tôi đã triển khai một phần mở rộng và một lớp 'BooleanBinding' cụ thể, nơi bạn có thể xác định xem có muốn liên kết ngược lại hay không dựa trên giải pháp của bạn! Tôi viết blog về nó ở đây: http://codewithpassion.blogspot.com/2010/11/binding-to-opposite-value-of-boolean.html –

1

Để làm điều này, tôi muốn làm một tài sản chỉ đọc tên NotSomeBool, trong cùng một lớp, nơi bạn có tài sản SomeBool, và liên kết với khách sạn này để thay thế.

+0

Đó lẫn lộn đối tượng miền, thêm hành vi UI đặc trưng cho nó. –

+0

Phải, đó là lý do tại sao tôi thích câu trả lời của Adam hơn :-) cảm ơn! – Javier

+0

+1 vẫn còn. Đó là một giải pháp cho vấn đề, không phải những gì tôi đang tìm kiếm. Cảm ơn bạn. –

6

Dựa trên câu trả lời của Adam Tôi đã viết một lớp helper nhỏ:

class NegateBinding 
{ 
    string propertyName; 
    object dataSource; 
    string dataMember; 
    public NegateBinding(string propertyName, object dataSource, string dataMember) 
    { 
     this.propertyName = propertyName; 
     this.dataSource = dataSource; 
     this.dataMember = dataMember; 
    } 

    public static implicit operator Binding(NegateBinding eb) 
    { 
     var binding = new Binding(eb.propertyName, eb.dataSource, eb.dataMember, false, DataSourceUpdateMode.OnPropertyChanged); 
     binding.Parse += new ConvertEventHandler(negate); 
     binding.Format += new ConvertEventHandler(negate); 
     return binding; 
    } 

    static void negate(object sender, ConvertEventArgs e) 
    { 
     e.Value = !((bool)e.Value); 
    } 
} 

Bây giờ bạn có thể sử dụng nó như thế này:

label1.DataBindings.Add(new NegateBinding("Visible", otherObject, "HasData")); 
+0

Giới thiệu tuyệt vời về toán tử ngầm và sử dụng khéo léo. – avenmore

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