Comencé a usar una lógica de conversión para controlar la salida visual de mi GUI basada en las propiedades de mi modelo, que se rellena desde SQL. Parece que también produce mucha sobrecarga y código, por lo que no estoy seguro de si implemento la tecnología de la manera correcta.

Aquí hay una instantánea:

enter image description here

Los botones de radio deshabilitan / habilitan algunos controles, es decir, porque las propiedades están vinculadas más de una vez y deben interpretarse de manera diferente, según el modo seleccionado.

El llamado modo es una propiedad de cadena en mi modelo "Modo de selección", lleno de uno de los tres valores (trimestre, mes, semana).

Para cada uno de los tres botones de radio, creé un convertidor de valor que se parece a lo siguiente:

class IsQuarterModeConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value != null)
            {
                if (value.ToString() == "Quarter")
                    return true;
            }
            return false;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return ((bool)value) ? "Quarter" : Binding.DoNothing;
        }
    }

Este es mi botón de radio XAML:

<RadioButton x:Name="G_rb_quarter" Content="Aktiv" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" GroupName="rbg_auswertungszeitraum" 
                                         IsChecked="{Binding MySelectedItem.Selectionmode, Converter={StaticResource IsQuarterModeConverter}}" />

Esto realmente funciona y siempre guarda el valor correcto en mi modelo, que se puede conservar en la base de datos para su uso posterior. Pero de verdad, ¿una clase con dos funciones para cada posible valor y elemento? No puedo creer que estoy haciendo esto de la manera correcta.

¿Algún consejo sobre esto?

2
kurdy 21 mar. 2017 a las 18:45

2 respuestas

La mejor respuesta

Hay (al menos) dos alternativas.

Primero , si desea usar un convertidor, entonces podría tener uno bastante genérico que use el ConverterParameter del enlace y se vea así:

public class SelectionModeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value?.ToString() == parameter.ToString();
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (bool)value ? parameter.ToString() : Binding.DoNothing;
    }
}

Su botón de opción ahora puede definir el Selectionmode que debería habilitar la selección:

<RadioButton IsChecked="{Binding MySelectedItem.Selectionmode,
    Converter={StaticResource SelectionModeConverter}, ConverterParameter=Quarter}" />

Los otros botones de opción obtendrían ConverterParameter=Month y ConverterParameter=Week respectivamente.

O segundo , podría colocar la lógica en su modelo de vista que podría verse así:

public class SelectionViewModel : INotifyPropertyChanged
{
    private string _selectionmode = null;

    public string Selectionmode
    {
        get { return _selectionmode; }
        set
        {
            if (_selectionmode == value)
                return;

            _selectionmode = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(IsQuarterSelected));
            OnPropertyChanged(nameof(IsMonthSelected));
            OnPropertyChanged(nameof(IsWeekSelected));
        }
    }

    public bool IsQuarterSelected
    {
        get { return Selectionmode == "Quarter"; }
        set { Selectionmode = value ? "Quarter" : Selectionmode; }
    }

    public bool IsMonthSelected
    {
        get { return Selectionmode == "Month"; }
        set { Selectionmode = value ? "Month" : Selectionmode; }
    }

    public bool IsWeekSelected
    {
        get { return Selectionmode == "Week"; }
        set { Selectionmode = value ? "Week" : Selectionmode; }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

Los botones de radio simplemente usarían estas propiedades:

<RadioButton IsChecked="{Binding MySelectedItem.IsQuarterSelected}" />

No puedo decir cuál de las dos formas posibles es la mejor en su caso porque eso realmente depende de la arquitectura de su aplicación y de cómo ha implementado su marco MVVM.

En mi caso, probablemente usaría las propiedades en el modelo de vista porque no me gusta usar muchos convertidores cuando estoy usando MVVM.

1
haindl 21 mar. 2017 a las 17:03

No necesitará un convertidor por valor si usa converterParameter:

public class SelectionModeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null)
        {
            if (value.ToString() == (string)parameter)
                return true;
        }
        return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return ((bool)value) ? parameter : Binding.DoNothing;
    }
}

Y también agregue ConverterParameter al enlace:

IsChecked="{Binding MySelectedItem.Selectionmode, 
                    ConverterParameter='Quater',
                    Converter={StaticResource IsQuarterModeConverter}}" 
1
ASh 21 mar. 2017 a las 16:46
42931861