L'utilisateur sélectionne quelque chose dans combobox, quelque chose d'autre est envoyé à la dépendance des biens
-
21-09-2019 - |
Question
Dans mon application, l'utilisateur peut choisir la façon dont une date est affichée. La plupart des chaînes de format standard datetime peuvent être choisi. Mon problème est maintenant que le doesnt utilisateur moyen de comprendre la différence entre « m » et « D ». Ce que je veux faire est changer cela pour que, comme Excel ne, plutôt que de montrer la chaîne de format, je montre comment une date arbitraire ressemblerait à l'aide de ce format.
Le WPF ComboBox SelectedItem est lié à une propriété de dépendance dans le sélecteur de format de date CLAS, qui contrôle l'autre contenant ce sélecteur de date fixe également.
Exemple :
- L'utilisateur sélectionne « Janvier, 15 » de sorte que la propriété de dépendance est réglé sur « m ».
- Par code derrière, la valeur de la propriété de dépendance est réglé sur « D », le combobox est mis à jour pour afficher « Jeudi, 15 Janvier 1970 » comme l'é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é pour créer une certaine date.
La solution
Vous pouvez créer un DateFormatChoice
de classe qui contient une propriété pour le code de format (par exemple, « m » ou « D ») et une propriété pour la date actuelle au format de cette façon.
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 comme 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'objet DateFormatChoice
choisi, 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 / réglage ce qui est choisi. Ne pas utiliser ValueMember
peut-être un peu plus facile.
Voici un exemple plus complet. Il utilise la classe DateFormatChoice
ci-dessus.
Tout d'abord, une collection 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'ai pas eu un contrôle de sélecteur de date qui a accepté les codes standards de format de chaîne, donc je fait un UserControl assez stupide (avec de nombreux 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 changé 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>