2008-12-05 49 views
8

Tôi có một trường nhị phân trong cơ sở dữ liệu của mình khó mô tả trong giao diện người dùng bằng cách sử dụng một hộp kiểm "Is XXXX?" - type. Tôi muốn sử dụng một cặp nút radio (ví dụ: "Thực hiện theo cách Foo" và "Thực hiện theo cách Bar"), nhưng hiện tại tất cả các trường khác trên biểu mẫu của tôi đều được liên kết dữ liệu với đối tượng kinh doanh. Tôi cũng muốn kết nối dữ liệu các cặp nút radio với đối tượng nghiệp vụ, nhưng chưa đưa ra một cách tốt để làm điều đó. Tôi có thể gắn một trong các nút vào trường, sao cho trường được đặt "true" nếu nút được chọn, nhưng trong khi chọn nút khác thì bỏ chọn nút đầu tiên (nghĩa là, hai nút radio được ghép nối đúng cách), giá trị của trường không cập nhật để phản ánh điều này.Tôi làm cách nào để sử dụng dữ liệu kết nối với nút radio Windows Forms?

Tôi muốn để có thể nói

button1.DataBindings.Add(new Binding("checked", source, "useFoo")); 
button2.DataBindings.Add(new Binding("checked", source, "!useFoo")); 

nhưng tôi khá chắc chắn rằng sẽ ném khi nó chạy. Có cách nào dễ hơn không, hoặc tôi có nên suy nghĩ nhiều hơn về cách viết một hộp kiểm không? Tôi không muốn thêm các chức năng bổ sung để xử lý điều gì đó tầm thường này ...

ETA: Người nhận xét đã đề xuất xem xét một menu thả xuống (ComboBox). Tôi đã nghĩ về điều này, nhưng làm thế nào tôi sẽ kết nối dữ liệu đó với một trường boolean trong một cơ sở dữ liệu/thuộc tính trong một đối tượng nghiệp vụ? Nếu tôi liên kết SelectedItem với thuộc tính useFoo, cái gì sẽ đi vào bộ sưu tập Items? Tôi có phải thêm chỉ "True" và "False", hoặc bằng cách nào đó tôi có thể thêm một đối tượng cặp khóa/giá trị liên kết một mục được hiển thị ("Sử dụng Foo"/"Không sử dụng Foo") với giá trị boolean đằng sau nó? Tôi đang gặp khó khăn khi tìm tài liệu về điều này.


Về câu trả lời: giải pháp tôi vết thương bằng cách sử dụng liên quan đến sửa đổi các đối tượng kinh doanh - ý tưởng cơ bản là rất giống với một đăng bởi Gurge, nhưng tôi đến với nó một cách riêng biệt trước khi tôi đọc câu trả lời của mình. Tóm lại, tôi đã thêm một thuộc tính riêng biệt chỉ đơn giản trả về !useFoo. Một nút radio được gắn với source.UseFoo và nút còn lại được gắn với source.UseBar (tên của thuộc tính mới). Điều quan trọng là phải đảm bảo tài sản mới có cả getters và setters, hoặc bạn sẽ kết thúc với hành vi thực sự kỳ quặc.

Trả lời

1

Tôi đã tìm thấy cách thực hiện việc này bằng cách sử dụng DataSet/DataTable.

Tôi tạo cột được tính toán trong DataTable với biểu thức IIF (Foo = true, false, true). Hãy gọi cột đó là Bar.

Thanh thuộc loại Boolean. Bây giờ bạn có thể ràng buộc một radiobutton.checked để Foo và một đến Bar.

Để có được Bar kiểm tra/bỏ chọn để tuyên truyền về Foo bạn phải đi vào mã DataTable được tạo ra và thêm một dòng, người cuối cùng trong mẫu này:

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 
     public bool Bar { 
      get { 
       try { 
        return ((bool)(this[this.tableradio.BarColumn])); 
       } 
       catch (global::System.InvalidCastException e) { 
        throw new global::System.Data.StrongTypingException("The value for column \'Bar\' in table \'radio\' is DBNull.", e); 
       } 
      } 
      set { 
       this[this.tableradio.BarColumn] = value; 
       this[this.tableradio.FooColumn] = !value; 
      } 
     } 
+2

Và đừng quên thực hiện thay đổi này mỗi khi bạn chỉnh sửa Số liệu của mình! :-( – Mac

-3

Bạn chỉ phải liên kết một trong các điều khiển miễn là bạn đảm bảo chúng nằm trong cùng một nhóm.

Bạn cũng có thể xem xét DropDown.

+1

Hãy thử điều này: thực hiện một cặp nút radio và hộp kiểm, đồng thời ràng buộc một nút radio và hộp kiểm đến cùng thuộc tính boolean trong một bindingsource. Chọn hộp kiểm và chuyển đổi radio - không có gì xảy ra. Bây giờ, nếu bạn * bỏ chọn hộp kiểm, sau đó bật, bạn có thể bật, nhưng không bao giờ tắt. – Coderer

1

Nếu đối tượng doanh nghiệp của bạn thực hiện INotifyPropertyChanged (mà làm cho công việc ràng buộc đẹp hơn), bạn có thể thêm đoạn mã sau vào giao diện trực quan nơi mà đối tượng doanh nghiệp của bạn là BO và được khai báo là có dấu và BO.Value là thuộc tính boolean mà bạn muốn liên kết.

Public Property NotValue() As Boolean 
    Get 
     Return Not BO.Value 
    End Get 
    Set(ByVal value As Boolean) 
     BO.Value = Not value 
     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("NotValue")) 
    End Set 
End Property 


Private Sub BO_PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Handles BO.PropertyChanged 
    If e.PropertyName = "Value" Then 
     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("NotValue")) 
    End If 
End Sub 

Các ràng buộc sau đây sẽ kết nối các nút radio.

RBTrue.DataBindings.Add(New Binding("Checked", Me.BO, "Value", False, DataSourceUpdateMode.OnPropertyChanged)) 
RBFalse.DataBindings.Add(New Binding("Checked", Me, "NotValue", False, DataSourceUpdateMode.OnPropertyChanged)) 

Giao diện trực quan cũng nên triển khai INotifyPropertyChanged. Phương thức này hoạt động theo cả hai cách: giá trị ban đầu được cập nhật nếu giao diện thay đổi và nếu giá trị ban đầu thay đổi giao diện sẽ cập nhật chính xác.

5
  1. Liên kết RadioButton được liên kết trực tiếp với giá trị boolean của bạn (ví dụ: được kiểm tra khi giá trị là true).
  2. Thêm một event handler cho sự kiện CheckedChanged trên RadioButton này trông giống như sau:

    private void radioButton_CheckedChanged(object sender, EventArgs e) 
    { 
        foreach (Binding b in ((Control)sender).DataBindings) 
         b.WriteValue(); 
    } 
    
1

tôi đi qua cùng một vấn đề, và phát hiện ra nó thực sự có thể với databinding tiêu chuẩn:

button1.DataBindings.Add(new Binding("checked", source, "useFoo", false, DataSourceUpdateMode.OnPropertyChanged); 
// no need to databind button 2, since button1.checked 
// is set to false when button2 is checked 

Theo mặc định, DataSourceUpdateMode được đặt thành OnValidation. Bằng cách đặt nó thành OnPropertyChanged, thay đổi được truyền ngay lập tức đến đối tượng dữ liệu.

Đối tượng kinh doanh của tôi triển khai INotifyPropertyChanged;

Bằng cách kiểm tra giải pháp này, tôi phát hiện ra rằng sự kiện OnPropertyChanged của tôi đã được kích hoạt hai lần khi tôi nhấp vào button2. Để ngăn chặn điều này, chỉ cần đặt

button1.CausesValidation = false; 
button2.CausesValidation = false; 

như ở đây: TextBox leave causes PropertyChanged get fired twice

1

làm nó bằng tay trong mã. Khi bạn tải biểu mẫu, hãy đặt các nút radio của bạn theo cơ sở dữ liệu của bạn. Khi bạn nhấn nút "lưu" nút lưu trữ nhà nước như bạn muốn. Ví dụ này lưu trữ radio dưới dạng các trường bit trong cơ sở dữ liệu.

 // Load radio state 
     radioButton1.Checked = ((myModel)myBindingSource.DataSource).boolOption1; 
     radioButton2.Checked = ((myModel)myBindingSource.DataSource).boolOption2; 

-

 // Save radio state 
     ((myModel)myBindingSource.DataSource).boolOption1 = radioButton1.Checked; 
     ((myModel)myBindingSource.DataSource).boolOption2 = radioButton2.Checked; 

Tôi cố gắng để kéo các mục từ "Data Sources" bảng điều khiển trong Visual Studio 2015 khi tôi định nghĩa nút radio của tôi như là phép toán trong bảng nhưng có vấn đề với các phép toán luận không đang được cập nhật thành false khi một nút radio khác được chọn. Khi thay đổi "causValidation" thành các nút vô tuyến giả không được chọn tự động khi nhảy giữa các trường nhập văn bản khác.

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