Пользователь выбирает что-то в combobox, что-то еще отправляется в свойство dependency
-
21-09-2019 - |
Вопрос
В моем приложении пользователь может выбрать способ отображения даты.Большая часть стандартные строки формата даты и времени может быть выбран.Моя проблема сейчас в том, что среднестатистический пользователь не понимает разницы между "m" и "D". То, что я хочу сделать, это измените это так, чтобы, как это делает Excel, вместо отображения строки формата я показывал, как будет выглядеть произвольная дата при использовании этого формата.
WPF combobox SelectedItem привязан к свойству зависимости в классе средств выбора формата даты, к которому также привязывается другой элемент управления, содержащий это средство выбора даты.
Пример:
- Пользователь выбирает "15 января", поэтому свойству dependency присваивается значение "m".
- С помощью кода ниже значение свойства dependency устанавливается равным "D", поле со списком обновляется, чтобы отображать "Четверг, 15 января 1970" в качестве выбранного элемента.
Я пытался использовать конвертеры, но обратный конвертация была невозможна, так как я не могу извлечь строку формата, используемую для создания определенной даты.
Решение
Вы могли бы создать класс DateFormatChoice
который содержит свойство для кода формата (например, "m" или "D") и свойство для текущей даты, отформатированной таким образом.
public class DateFormatChoice {
public string FormatCode { get; private set; }
public string CurrentDateExample {
get { return DateTime.Now.ToString( FormatCode ) }
}
public DateFormatChoice( string standardcode ) {
FormatCode = standardcode;
}
}
Вы привязываете свой ComboBox к их коллекции, используя CurrentDateExample
в любом из ваших DataTemplate
или в виде выпадающего списка DisplayMemberPath
.Вы можете либо использовать эти объекты непосредственно с вашим классом выбора формата даты, либо DatePicker
привязывается к FormatCode
свойство выбранного DateFormatChoice
объект, или вы можете установить ValueMemberPath
свойство в исходном выпадающем списке для FormatCode
собственность и использование SelectedValue
в выпадающем списке для получения / настройки того, что выбрано.Не использующий ValueMember
могло бы быть немного проще.
Вот более полный пример.Он использует DateFormatChoice
классом выше.
Во-первых, сбор данных.
public class DateFormatChoices : List<DateFormatChoice> {
public DateFormatChoices() {
this.Add( new DateFormatChoice( "m" ) );
this.Add( new DateFormatChoice( "d" ) );
this.Add( new DateFormatChoice( "D" ) );
}
}
Затем я создал простую ViewModel для окна:
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 ) );
}
}
У меня не было элемента управления date picker, который принимал стандартные коды формата string, поэтому я создал довольно тупой UserControl (со многими обрезанными углами), просто чтобы продемонстрировать получение им кода формата.Я дал ему свойство зависимости, называемое DateFormatProperty
типа string
и указал измененное значение обратного вызова в UIPropertyMetadata
.
<Grid>
<TextBlock Name="datedisplayer" />
</Grid>
Обратный вызов:
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 );
}
}
И вот как я связал все это вместе на Витрине.
<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>