يحدد المستخدم شيئًا ما في Combobox ، يتم إرسال شيء آخر إلى خاصية التبعية
-
21-09-2019 - |
سؤال
في طلبي ، يمكن للمستخدم تحديد كيفية عرض التاريخ. أكثر من سلاسل تنسيق الوقت القياسية يمكن اختياره. مشكلتي الآن هي أن المستخدم العادي لا يفهم الفرق بين "M" و "D". ما أريد أن أفعله هو قم بتغيير هذا بحيث ، كما يفعل Excel ، بدلاً من إظهار سلسلة التنسيق ، أوضح كيف يبدو تاريخ التعسفي استخدام هذا التنسيق.
يرتبط WPF ComboBox SelectionItem بخاصية التبعية في تنسيق التاريخ CLAS ، والذي يربط عنصر التحكم الآخر الذي يحتوي على منتقي التاريخ أيضًا.
مثال:
- يختار المستخدم "يناير ، 15" بحيث يتم تعيين خاصية التبعية على "M".
- من خلال الكود وراء ، يتم تعيين قيمة خاصية التبعية على "D" ، يتم تحديث Combobox لعرض "الخميس ، 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
أو كما combobox DisplayMemberPath
. يمكنك إما استخدام هذه الكائنات مباشرة مع فئة تنسيق التاريخ الخاص بك و DatePicker
يرتبط بـ FormatCode
خاصية المختار DateFormatChoice
كائن ، أو يمكنك تعيين ملف ValueMemberPath
خاصية على comboBox الأصلي إلى FormatCode
الممتلكات والاستخدام SelectedValue
على combobox للحصول على/تحديد ما يتم اختياره. عدم استخدام 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 ) );
}
}
لم يكن لدي عنصر تحكم في منتقي التاريخ قبل رموز تنسيق السلسلة القياسية ، لذلك قمت بعمل 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>