يحدد المستخدم شيئًا ما في Combobox ، يتم إرسال شيء آخر إلى خاصية التبعية

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

سؤال

في طلبي ، يمكن للمستخدم تحديد كيفية عرض التاريخ. أكثر من سلاسل تنسيق الوقت القياسية يمكن اختياره. مشكلتي الآن هي أن المستخدم العادي لا يفهم الفرق بين "M" و "D". ما أريد أن أفعله هو قم بتغيير هذا بحيث ، كما يفعل Excel ، بدلاً من إظهار سلسلة التنسيق ، أوضح كيف يبدو تاريخ التعسفي استخدام هذا التنسيق.

يرتبط WPF ComboBox SelectionItem بخاصية التبعية في تنسيق التاريخ CLAS ، والذي يربط عنصر التحكم الآخر الذي يحتوي على منتقي التاريخ أيضًا.

مثال:

  1. يختار المستخدم "يناير ، 15" بحيث يتم تعيين خاصية التبعية على "M".
  2. من خلال الكود وراء ، يتم تعيين قيمة خاصية التبعية على "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>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top