El usuario selecciona algo en cuadro combinado, algo más se envía a la dependencia propiedad

StackOverflow https://stackoverflow.com/questions/2287190

Pregunta

En mi aplicación, el usuario puede seleccionar cómo se muestra una fecha. La mayoría de las cadenas de formato de fecha y hora pueden ser seleccionado. Mi problema ahora es que el imposible de media usuario a entender la diferencia entre "m" y "D". Lo que quiero hacer es cambiar esto para que, al igual que Excel, en lugar de mostrar la cadena de formato, se muestra cómo una fecha arbitraria se vería utilizando ese formato.

El SelectedItem combobox WPF se une a una propiedad de dependencia en las clas recogedor de formato de fecha, que el otro control que contiene este selector de fechas también se une a.

Ejemplo :

  1. El usuario selecciona "Enero, 15" por lo que la propiedad de dependencia está ajustado a "m".
  2. A través de código subyacente, el valor de la propiedad de dependencia se establece en "D", el cuadro combinado se actualiza para mostrar "Jueves, 15 de enero de 1970" como el elemento seleccionado.

He intentado utilizar convertidores pero ConvertBack era imposible, ya que no puedo extraer una cadena de formato utilizado para crear una fecha determinada.

¿Fue útil?

Solución

Se puede crear un DateFormatChoice clase que contiene una propiedad para el código de formato (por ejemplo, "m" o "D") y una propiedad para la fecha actual con formato de esa manera.

public class DateFormatChoice {
    public string FormatCode { get; private set; }
    public string CurrentDateExample {
        get { return DateTime.Now.ToString( FormatCode ) }
    }

    public DateFormatChoice( string standardcode ) {
        FormatCode = standardcode;
    }
}

Enlaza tu ComboBox a una colección de éstos usando CurrentDateExample ya sea en su DataTemplate o como DisplayMemberPath del ComboBox. Puede utilizar estos objetos directamente con su clase selector de formato de fecha y el DatePicker se une a la propiedad FormatCode del objeto DateFormatChoice elegido, o puede establecer la propiedad ValueMemberPath en el cuadro combinado original a la propiedad FormatCode y utilizar SelectedValue en el cuadro combinado para conseguir / establecer lo que se elija. No usar ValueMember podría ser un poco más fácil.


Este es un ejemplo más completo. Se utiliza la clase DateFormatChoice anteriormente.

En primer lugar, una colección de datos.

public class DateFormatChoices : List<DateFormatChoice> {
    public DateFormatChoices() {
        this.Add( new DateFormatChoice( "m" ) );
        this.Add( new DateFormatChoice( "d" ) );
        this.Add( new DateFormatChoice( "D" ) );
    }
}

Entonces hice modelo de vista simple para la ventana:

public class ViewModel : INotifyPropertyChanged {
    public event PropertyChangedEventHandler PropertyChanged = ( s, e ) => {
    }; // the lambda ensures PropertyChanged is never null

    public DateFormatChoices Choices {
        get;
        private set;
    }

    DateFormatChoice _chosen;
    public DateFormatChoice Chosen {
        get {
            return _chosen;
        }
        set {
            _chosen = value;
            Notify( PropertyChanged, () => Chosen );
        }
    }

    public DateTime CurrentDateTime {
        get {
            return DateTime.Now;
        }
    }

    public ViewModel() {
        Choices = new DateFormatChoices();
    }

    // expression used to avoid string literals
    private void Notify<T>( PropertyChangedEventHandler handler, Expression<Func<T>> expression ) {
        var memberexpression = expression.Body as MemberExpression;
        handler( this, new PropertyChangedEventArgs( memberexpression.Member.Name ) );
    }
}

Yo no tenía un control de selector de fechas que acepta los códigos de formato de cadena estándar, así que hice un control de usuario bastante tonto (con muchas esquinas cortadas) sólo para demostrar su recibo de la código de formato. Se lo di una propiedad de dependencia llamada DateFormatProperty de tipo string y ha especificado una devolución de llamada cambiado valor en el UIPropertyMetadata.

<Grid>
    <TextBlock Name="datedisplayer" />
</Grid>

La devolución de llamada:

private static void DateFormatChanged( DependencyObject obj, DependencyPropertyChangedEventArgs e ) {
    var uc = obj as UserControl1;
    string code;
    if ( null != ( code = e.NewValue as string ) ) {
        uc.datedisplayer.Text = DateTime.Now.ToString( code );
    }
}

Y así es como me lo até todos juntos en la ventana.

<StackPanel>
    <StackPanel.DataContext>
        <local:ViewModel />
    </StackPanel.DataContext>
    <ComboBox
        ItemsSource="{Binding Choices}" DisplayMemberPath="CurrentDateExample"
        SelectedItem="{Binding Chosen, Mode=TwoWay}"/>
    <local:UserControl1
        DateFormatProperty="{Binding Chosen.FormatCode}" />
</StackPanel>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top