2010-02-18 6 views
0

Dans mon application, l'utilisateur peut sélectionner la manière dont une date est affichée. La plupart des standard datetime format strings peuvent être sélectionnés. Mon problème maintenant est que l'utilisateur moyen ne comprend pas la différence entre "m" et "D". Ce que je veux faire est changer cela afin que, comme Excel, plutôt que d'afficher la chaîne de format, je montre comment une date arbitraire ressemblerait à l'aide de ce format. La liste déroulante WPF combobox SelectedItem est liée à une propriété de dépendance dans les clas du sélecteur de format de date, à laquelle l'autre contrôle contenant ce sélecteur de date se lie également.L'utilisateur sélectionne un élément dans la zone de liste déroulante, un autre élément est envoyé à la propriété de dépendance

Exemple:

  1. L'utilisateur sélectionne "Janvier, 15" de sorte que la propriété de dépendance est réglé sur "m".
  2. Avec le code derrière, la valeur de la propriété de dépendance est définie sur "D", la zone de liste déroulante est mise à jour pour afficher "Jeudi, 15 Janvier 1970" comme élément sélectionné.

J'ai essayé d'utiliser des convertisseurs mais ConvertBack était impossible car je ne peux pas extraire une chaîne de format utilisée pour créer une certaine date.

Répondre

1

Vous pouvez créer une classe DateFormatChoice qui contient une propriété pour le code de format (par exemple, "m" ou "D") et une propriété pour la date actuelle formatée de cette manière.

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

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

Vous liez votre ComboBox à une collection de ces utilisant CurrentDateExample soit dans votre DataTemplate ou DisplayMemberPath du ComboBox. Vous pouvez utiliser ces objets directement avec votre classe de sélecteur de format de date et le DatePicker se fixe à la propriété FormatCode de l'élu objet DateFormatChoice, ou vous pouvez définir la propriété ValueMemberPath sur la ComboBox originale à la propriété FormatCode et utiliser SelectedValue sur la zone de liste déroulante pour obtenir/définir ce qui est choisi. Ne pas utiliser ValueMember pourrait être un peu plus facile.


Voici un exemple plus complet. Il utilise la classe DateFormatChoice ci-dessus.

D'abord, une collecte de données.

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

Alors je fait simples ViewModel pour la fenêtre:

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)); 
    } 
} 

je n'avais pas un contrôle de sélecteur de date qui a accepté les codes standards de format de chaîne, donc je fait une UserControl assez stupide (avec beaucoup coins coupés) juste pour démontrer sa réception du code de format. Je lui ai donné une propriété de dépendance appelée DateFormatProperty de type string et spécifié une valeur de rappel modifiée dans le UIPropertyMetadata.

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

Le rappel:

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); 
    } 
} 

Et voilà comment je ligoté tous ensemble dans la fenêtre.

<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>