2013-09-04 18 views
11

Mam grupę z niektórymi radiobuttons. Jak mogę się dowiedzieć, który z nich jest sprawdzany? Używam WPF i po MVVM.Wyznaczenie sprawdzonej funkcji Radiobutton z groupbox w WPF po MVVM

<GroupBox Name="grpbx_pagerange" Header="Print Range"> 
    <Grid > 
     <RadioButton Name="radbtn_all" Content="All Pages" GroupName="radios_page_range" IsChecked="True" /> 
     <RadioButton x:Name="radbtn_curr" Content="Current Page" GroupName="radios_page_range" /> 
     <RadioButton Name="radbtn_pages" Content="Page Range" GroupName="radios_page_range" /> 

     .... 

</GroupBox> 

Teraz jeden sposób mogę dowiedzieć się było związać każdego Radiobutton za IsChecked obiekt do jakiejś nieruchomości w ViewModel a następnie zrobić if..else rodzaj logiki w moim ViewModel, aby dowiedzieć się wybranego RadioButton.

Ale czy istnieje inny elegancki sposób?

Odpowiedz

27

można związać RadioButton.Command Radiobuttons z poleceniem swojego ViewModel i wysłać unikatowy CommandParameter, aby zidentyfikować, który przycisk wywołał polecenie w przyborniku.

<RadioButton Command="{Binding MyCommand}" CommandParameter="Radio1"/> 
<RadioButton Command="{Binding MyCommand}" CommandParameter="Radio2"/> 
<RadioButton Command="{Binding MyCommand}" CommandParameter="Radio3"/> 

w programie obsługi komendy sprawdź parametr identyfikujący radiobutton.

Dzięki

+0

Hi @nit: Jest to bardzo proste, szybkie, eleganckie i rzeczywiście warte rozwiązania. Dzięki za odpowiedź. :) – Bhramar

+0

@Bhramar cieszę się, że zadziałało dla ciebie :) – Nitin

+1

Buddy, Rozwiązanie działa dobrze, ALE jak ustawić domyślne sprawdzone do któregokolwiek z mojego RadioButton. Możemy ustawić go w contructor, ale to naruszy zasady MVVM. Wszelkie pomysły byłyby pomocne. – Bhramar

18

można utworzyć enum zawierający Wartości RadioButton obiektów jak nazwy (w przybliżeniu), a następnie wiążą właściwość IsChecked do właściwości typu tego enum stosując EnumToBoolConverter.

public enum Options 
{ 
    All, Current, Range 
} 

Następnie w modelu widoku lub kodu tyle:

private Options options = Options.All; // set your default value here 

public Options Options 
{ 
    get { return options; } 
    set { options = value; NotifyPropertyChanged("Options"); } 
} 

Dodaj Converter:

[ValueConversion(typeof(Enum), typeof(bool))] 
public class EnumToBoolConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value == null || parameter == null) return false; 
     string enumValue = value.ToString(); 
     string targetValue = parameter.ToString(); 
     bool outputValue = enumValue.Equals(targetValue, StringComparison.InvariantCultureIgnoreCase); 
     return outputValue; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value == null || parameter == null) return null; 
     bool useValue = (bool)value; 
     string targetValue = parameter.ToString(); 
     if (useValue) return Enum.Parse(targetType, targetValue); 
     return null; 
    } 
} 

Wtedy wreszcie dodać powiązań w interfejsie użytkownika, ustawiając odpowiednią ConverterParameter:

<RadioButton Content="All Pages" IsChecked="{Binding Options, Converter={ 
    StaticResource EnumToBoolConverter}, ConverterParameter=All}" /> 
<RadioButton Content="Current Page" IsChecked="{Binding Options, Converter={ 
    StaticResource EnumToBoolConverter}, ConverterParameter=Current}" /> 
<RadioButton Content="Page Range" IsChecked="{Binding Options, Converter={ 
    StaticResource EnumToBoolConverter}, ConverterParameter=Range}" /> 

Teraz możesz stwierdzić, które ustawienie jest ustawione, patrząc na zmienną Options w modelu widoku lub kodu z tyłu. Będziesz także mógł ustawić sprawdzane RadioButton, ustawiając właściwość Options.

+0

Hej @Sheridan: Twoje rozwiązanie wygląda świetnie, szczególnie cechy 'Enum' &' Converter'. Ale nie mogę przydzielić statycznego zasobu w Window.Resource - byłoby to użyteczne - jeśli mógłbyś dodać swój widok definiowania statycznego zasobu. Dzięki. :) – Bhramar

+0

@Bhramar możesz dołączyć konwerter w ten sposób: najpierw dołącz przestrzeń nazw xmlns: local == "clr-namespace: WpfApplication1" i, e to przestrzeń nazw, w której deklarowany jest konwerter. następnie w Window.Rsources dodaj Nitin

+0

Próbowałem tego: ' ' To po prostu nie działa. Odesłałem to [artykuł] (http://www.amazedsaint.com/2009/08/mvvm-binding-multiple-radio-buttons-to.html) Błąd mówi- "EnumToBoolConverter" nie istnieje w przestrzeni nazw "clr-namespace: MNCore.Control" – Bhramar

-4

Mam ten sam problem i rozwiązany przez usunięcie "GroupName" Właściwość z Radiobutton.

Proszę usunąć właściwość "GroupName" ze wszystkich przycisków opcji. i sprawdzić

1

Jest też inny sposób MVVM, aby rozwiązać ten przy użyciu IsChecked obiekt

Oto XAML

<Page> 
<Page.Resources> 
<DataTemplate x:Key="ChoiceItemTemplate"> 
<RadioButton Content="{Binding individualRadioButtonText}" 
    IsTabStop="True" 
    GroupName="choice" 
    IsChecked="{Binding IsChecked, Mode=TwoWay}"/> 
</DataTemplate> 
</Page.Resources> 


<StackPanel> 
    <TextBlock Text="{Binding ChoiceQuestion}" /> 
<ItemsControl ItemsSource="{Binding ListOfAnswerOptions}" 
       ItemTemplate="{StaticResource ChoiceItemTemplate}" /> 
</StackPanel> 
</Page> 

Twój model będzie coś takiego

public class RadioButtonQuestion 
{ 
    public string ChoiceQuestion { get; set; } 
    public string answer { get; set; } 
    public List<AnswerOption> ListOfAnswerOptions { get; set; } 
} 

public class AnswerOption 
{ 
    public string individualRadioButtonText { get; set; } 
    public bool IsChecked { get; set; } 
} 

ViewModel będzie wyglądać w ten sposób (logika wyboru)

RadioButtonQuestion r = new RadioButtonQuestion(); 
var selectedElement = rbuttonQuestion.answerOptions.FirstOrDefault(c => c.IsChecked); 
r.answer = selectedElement.individualRadioButtonText; 

Więc jeśli ustawisz datacontext widoku dla tego viewmodel. Musisz być w stanie go uruchomić.

Mam nadzieję, że to pomaga.

1

Jeśli używasz właściwość Tag na opcjach przycisków (Boolean, Integer, smyczki) jak w jego XAML

<StackPanel Orientation="Horizontal" Margin="10,10, 0, 0"> 
    <RadioButton Name="rP0" Content="Low " Tag="0" /> 
    <RadioButton Name="rP1" Content="Normal" Tag="1" IsChecked="True" /> 
    <RadioButton Name="rP2" Content="Medium" Tag="2" /> 
    <RadioButton Name="rP3" Content="High" Tag="3" /> 
</StackPanel> 

Następnie można użyć następujących funkcji, aby uzyskać wybraną wartość (przycisk)

int priority = SelectedRadioValue<int>(0, rP0, rP1, rP2, rP3); 

gdzie

public T SelectedRadioValue<T>(T defaultValue, params RadioButton[] buttons) 
{ 
    foreach (RadioButton button in buttons) 
    { 
     if (button.IsChecked == true) 
     { 
      if (button.Tag is string && typeof(T) != typeof(string)) 
      { 
       string value = (string) button.Tag; 
       return (T) Convert.ChangeType(value, typeof(T)); 
      } 

      return (T)button.Tag; 
     } 
    } 

    return defaultValue; 
}