سؤال

هل هناك أي أطر ربط البيانات (BCL أو غير ذلك) تسمح بالربط بين أي خاصيتين CLR التي تنفذ INotifyPropertyChanged و INotifyCollectionChanged؟يبدو أنه يجب أن يكون من الممكن القيام بشيء مثل هذا:

var binding = new Binding();
binding.Source = someSourceObject;
binding.SourcePath = "Customer.Name";
binding.Target = someTargetObject;
binding.TargetPath = "Client.Name";
BindingManager.Bind(binding);

أين someSourceObject و someTargetObject هي مجرد POCOs التي يتم تنفيذها INotifyPropertyChanged.ومع ذلك، لست على علم بأي دعم BCL لهذا، ولست متأكدًا مما إذا كانت هناك أطر عمل موجودة تسمح بذلك.

تحديث:وبما أنه لا توجد مكتبة متاحة، فقد أخذت على عاتقي أن أكتب مكتبتي الخاصة.إنه متاح هنا.

شكرًا

هل كانت مفيدة؟

المحلول

تروس لملء الفراغ.

نصائح أخرى

أنا لست على علم بأي مكتبة يقوم بذلك - ولكن يمكنك كتابة ما تريد بسهولة إلى حد ما.

إليك الأساس الذي طرحته في بضع دقائق والذي يحدد ربط البيانات في اتجاهين بين خاصيتين بسيطتين:

public static class Binder
{

    public static void Bind(
        INotifyPropertyChanged source,
        string sourcePropertyName,
        INotifyPropertyChanged target,
        string targetPropertyName)
    {
        var sourceProperty
            = source.GetType().GetProperty(sourcePropertyName);
        var targetProperty
            = target.GetType().GetProperty(targetPropertyName);

        source.PropertyChanged +=
            (s, a) =>
            {
                var sourceValue = sourceProperty.GetValue(source, null);
                var targetValue = targetProperty.GetValue(target, null);
                if (!Object.Equals(sourceValue, targetValue))
                {
                    targetProperty.SetValue(target, sourceValue, null);
                }
            };

        target.PropertyChanged +=
            (s, a) =>
            {
                var sourceValue = sourceProperty.GetValue(source, null);
                var targetValue = targetProperty.GetValue(target, null);
                if (!Object.Equals(sourceValue, targetValue))
                {
                    sourceProperty.SetValue(source, targetValue, null);
                }
            };
    }
}

وبطبيعة الحال، هذا الرمز يفتقر إلى بعض التفاصيل الدقيقة.الأشياء التي يجب إضافتها تشمل

  • التحقق من ذلك source و target تم تعيينها
  • التحقق من أن الخصائص التي تم تحديدها من قبل sourcePropertyName و targetPropertyName يخرج
  • التحقق من توافق النوع بين الخاصيتين

كما أن الانعكاس بطيء نسبيًا (على الرغم من قياسه قبل التخلص منه، فهو ليس كذلك الذي - التي بطيئة)، لذلك قد ترغب في استخدام التعبيرات المترجمة بدلاً من ذلك.

أخيرًا، نظرًا لأن تحديد الخصائص حسب السلسلة عرضة للخطأ، يمكنك استخدام تعبيرات Linq وطرق الامتداد بدلاً من ذلك.ثم بدلا من الكتابة

Binder.Bind( source, "Name", target, "Name")

يمكنك الكتابة

source.Bind( Name => target.Name);

AutoMapper يمكن نسخ القيم بين حالتين، ولكن لديك لكتابة التعليمات البرمجية الخاصة بك لجعل هذا يحدث تلقائيا.

التي يمكن ربطها LINQ أو <وأ href = "http://www.codeplex.com/ clinq "يختلط =" نوفولو noreferrer "> LINQ المستمر يمكن أن تساعد هنا. إذا كنت تحاول إضافة خصائص نموذج التي هي في الواقع "خصائص مستمدة" من الفعلي، البيانات تحديث، لجعل من الأسهل بالنسبة لك اجهة المستخدم لربط، يجب أن هذين الإطارين يساعد.

وكتبت في ربط المشروع مع الدعم الكامل للربط بين خصائص neasted المتزامن إجراءات ملزمة. وsintax لا يمكن أن يكون أكثر بساطة:

//Two way binding between neasted properties:
Bind.TwoWay(()=> client.Area.Data.Name == this.AreaName);

//On change action execute:
Bind
    .OnChange(()=> client.Personal.Name)
    .Do(x => clientName = x);

إذا قمت بتعريفه الممتلكات الخاصة بك كما DependencyProperty الصورة يمكنك أن تفعل ذلك. كلا WF وWPF لها تنفيذ ذلك (وصلة الأول لبرنامج الأغذية العالمي. لWF هو <وأ href = "http://msdn.microsoft.com/en-us/library/system.workflow.componentmodel.dependencyproperty.aspx "يختلط =" نوفولو noreferrer "> هذا واحد) لذلك عليك أن تقرر أي استخدام - ولكن على حد سواء ينبغي أن يكون كافيا لتلبية الاحتياجات الخاصة بك

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top