2009-06-01 7 views
5

Mam okno dialogowe WinForm, które zawiera 3 przyciski opcji. Używam ApplicationSettings do wiązania sprawdzonej właściwości każdego z tych kontrolek RadioButton, ale nie robi to, czego oczekuję. Teraz muszę kliknąć każdy przycisk radiowy dwa razy, zanim zostanie on sprawdzony, a wybrany przycisk radiowy nie będzie trwał.Użycie ApplicationSettings do przechowywania sprawdzonej właściwości dla WinForms RadioButtons

Czy istnieje wiersz kodu, który należy wykonać po zamknięciu formularza, który zapisuje ustawienia użytkownika?

Jak wyeliminować potrzebę dwukrotnego kliknięcia przycisków opcji?

Czy istnieje lepszy sposób na utrzymanie tego typu ustawień użytkownika? Mam właściwość publiczną w klasie okna dialogowego, która pobiera/ustawia wartość wyliczeniową na podstawie tego, który przycisk opcji jest zaznaczony, ale nie widzę łatwego sposobu powiązania tej właściwości z ustawieniem użytkownika.

Edytuj: Należy określić, że używam vb.net. Myślę, że to oznacza My.Settings zamiast Properties.Settings.

Odpowiedz

3

mogę odpowiedzieć na tę część pytania:

istnieje linia kodu muszę wykonać, gdy forma jest zamknięta, który zapisuje ustawienia użytkownika?

Ustawienia aplikacji są przechowywane w klasie Settings w przestrzeni nazw Properties. Klasa Settings ma nieruchomość statyczną o nazwie Default, która reprezentuje bieżące ustawienia dla aplikacji. Tak więc w przypadku zamknięcia na głównym formularzu, dzwonisz pod numer:

Properties.Settings.Default.Save(); 

... aby zapisać ustawienia.

Podobnie można dostać się do ustawień programowo przy użyciu nazwy ustawienia: Properties.Settings.Default.MyRadioButtonState (lub jakkolwiek to nazwałeś).

+0

dzięki! To doprowadziło mnie do właściwego kierunku. W vb.net to Moje ustawienia zamiast Właściwości.Settings.Default, ale poza tym działa idealnie. Mam teraz tylko jedno ustawienie i używam publicznej właściwości formularza w zdarzeniach Load i FormClosing. – CoderDennis

+0

Na moim komputerze nie jest konieczne zapisywanie ustawień podczas zamykania. Są one zapisywane automatycznie. Jedynym problemem jest to, że muszę kliknąć dwa razy. – systemovich

5

mi odpowiedzieć na to część pytania:

Jak wyeliminować potrzebę dwukrotnego kliknięcia przycisków opcji?

Możesz dodać następującą procedurę obsługi zdarzenia do zdarzenia kliknięcia każdej z trzech składników RadioButton (którego Sprawdzone właściwości są zobowiązane do Ustawienia aplikacji) w groupbox:

Private Sub RadioButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tomRadioButton.Click, dickRadioButton.Click, harryRadioButton.Click 
    If sender.Checked = False Then 
     sender.Checked = True 
    End If 
End Sub 

To działa, nawet chociaż trwa przytrzymanie pół sekundy, aby nie kliknięty RadioButton został sprawdzony po kliknięciu.

Przyczyną problemu zostało wyjaśnione dwa lata temu (w 2008 roku) w sekcji 5 słupka Surviving WinForms Databinding na blogu turbulentny Intellect (dziękuję, ohadsc na link):

Rule 5 : nie wiążą się klikalne Radio buttons

wiem jak wielkie byłoby gdybyś może po prostu związać swoją masę radia przycisków na właściwość enum. Naprawdę robię do. Myślisz, że po prostu wybierasz się do formatowania i analizy zdarzeń , aby przetłumaczyć je z powrotem na swoje wyliczenie, a wszystkie będą dobrze. Byłoby tak cholernie wygodne, gdyby rzeczywiście zadziałało. Ale WinForms po prostu nie jest do tego przystosowana. W przypadku 3 pełnych wersji (lub wersji 3.5 ?) Tak się stało. To ze względu na kolejność zdarzeń, która nie jest czymś, co MS może przejść przełączania się bez powodu tysięcy programistów, aby uzyskać naprawdę oszukany off.

Problem tak naprawdę sprowadza się do faktu, że w przeciwieństwie do danych innych Controls właściwości, sprawdzone właściwością przycisku radiowej faktycznie nie zmieni aż ostrości pozostawia opcję. I jak ze wszystkimi WinForms kontroluje ostrość nie faktycznie opuszczą przycisk radiowy aż po uwagę poświęca się kolejna kontrola, aw rzeczywistości nie aż po zdarzeniu Kliknij nowo skupionej kontroli został zwolniony. Wynik tego, ponieważ odnosi się do radiowych przycisków, jest to, że jeśli starają się wiązać je związanego właściwości twojej źródło danych będzie faktycznie pozostają stan wizualny swoich przycisków opcji o jeden kliknięcia. Jeśli masz tylko dwa przyciski radiowe , źródłem danych będzie dokładnie naprzeciwko widocznego stanu, , dopóki nie klikniesz gdzieś indziej, że nie wywoła akcji, która odwołuje się do właściwości źródła danych o wartości . Co może uczynić z tego naprawdę irytujący błąd do wyśledzenia. Niemal sądziłem, że mam halucynacje.

Teraz, szczerze mówiąc, można sprawić, żeby działało. Ale jest to najbrzydszy kludge, który kiedykolwiek kludował. Może być to nie jest takie złe ... ale na pewno jest to niechlujny hak na . Dużo pracy wymaga czegoś, co naprawdę powinno już być dostępne . Tak blisko, jak mogę powiedzieć, jedynym sposobem rozwiązania tego problemu nie rezygnując mechanizm Databinding jest zasadniczo zrobić własny RadioButton kontrolę ze zmianą własności i kolejności zdarzeń, które są rzeczywiście użyteczne. Możesz napisać od podstaw, lub podklasy RadioButton i zastąpić całą logiką zdarzeń za pomocą niestandardowej obsługi komunikatów .

6

Dziękuję Geoffrey Van Wyk i ohadsc (za link), wymyśliłem następującą kontrolę niestandardową. Jest to w zasadzie niestandardowa ramka, która automatycznie zaimplementuje kod Geoffrey'a na wszystkich zawartych w nim radiobutach. Zaletą jest to, że można teraz użyć ApplicationSettings do powiązania sprawdzonej właściwości kontrolki i będzie działać tak, jak powinna.

Oto moja C# kod, aby formant niestandardowy:

public partial class RadioPanel : System.Windows.Forms.Panel 
    { 
     protected override void OnControlAdded(ControlEventArgs e) 
     { 
      base.OnControlAdded(e); 
      var radioButton = e.Control as RadioButton; 
      if (radioButton != null) 
       radioButton.Click += radioButton_Click; 
     } 

     void radioButton_Click(object sender, EventArgs e) 
     { 
      var radio = (RadioButton)sender; 
      if (!radio.Checked) 
       radio.Checked = true; 
     } 

    }