মান রূপান্তরকারীরা কি তাদের মূল্যবানদের চেয়ে বেশি সমস্যায় পড়ে?


20

আমি ডাব্লুপিএফ অ্যাপ্লিকেশনটিতে এমন মতামত নিয়ে কাজ করছি যার জন্য অসংখ্য মান রূপান্তর প্রয়োজন। প্রাথমিকভাবে, আমার দর্শন ( এক্সএএমএল শিষ্যদের উপর এই সজীব আলোচনার অংশে অনুপ্রাণিত হয়েছিল) হ'ল আমার এই ভিউর মডেলটি দৃ of ়তার সাথে ডেটা প্রয়োজনীয়তার সমর্থন করার বিষয়ে কঠোরভাবে করা উচিত । এর অর্থ হ'ল ভিজিবিলিটি, ব্রাশ, মাপ ইত্যাদির মতো কোনও তথ্যে ডেটা পরিণত করার জন্য যে কোনও মান রূপান্তর প্রয়োজন, তা মান রূপান্তরকারী এবং বহু-মান রূপান্তরকারীদের দ্বারা পরিচালিত হবে। ধারণামূলকভাবে, এটি বেশ মার্জিত বলে মনে হয়েছিল। ভিউ মডেল এবং ভিউ উভয়েরই স্বতন্ত্র উদ্দেশ্য থাকবে এবং সুন্দরভাবে ডিকোপল হবে। "ডেটা" এবং "চেহারা" এর মধ্যে একটি স্পষ্ট লাইন আঁকানো হবে।

ভাল, এই কৌশলটি "পুরাতন কলেজ চেষ্টা করুন" দেওয়ার পরে, আমি এইভাবে বিকাশ চালিয়ে যেতে চাই কিনা সে সম্পর্কে আমার কিছু সন্দেহ রয়েছে। আমি প্রকৃতপক্ষে মান রূপান্তরকারীদের ডাম্প করার এবং দৃ model়ভাবে ভিউ মডেলের হাতে সমস্ত মান রূপান্তরকরণের জন্য দায়বদ্ধ করার বিষয়টি বিবেচনা করছি।

মান রূপান্তরকারীদের ব্যবহারের বাস্তবতা পরিষ্কারভাবে পৃথক করা উদ্বেগগুলির আপাত মান পর্যন্ত মাপছে বলে মনে হচ্ছে না। মান রূপান্তরকারীদের সাথে আমার বৃহত্তম সমস্যাটি হ'ল তারা ব্যবহার করতে ক্লান্ত। আপনাকে একটি নতুন শ্রেণি তৈরি করতে হবে, প্রয়োগ করতে হবে IValueConverterবা সঠিক ধরণের IMultiValueConverterথেকে মান বা মানগুলি নিক্ষেপ করতে হবে object, DependencyProperty.Unset(কমপক্ষে বহু-মান রূপান্তরকারীদের জন্য) পরীক্ষা করতে হবে, রূপান্তর যুক্তিটি লিখতে হবে, একটি উত্স অভিধানে রূপান্তরকারীকে নিবন্ধভুক্ত করতে হবে (নীচে আপডেট দেখুন ], এবং পরিশেষে, বরং ভার্ভোজ এক্সএএমএল ব্যবহার করে কনভার্টারটি সংযুক্ত করুন (যার ফলে উভয়কে বাঁধাই করার জন্য এবং রূপান্তরকারীর নামের জন্য যাদু স্ট্রিং ব্যবহার করতে হবে)[নীচে আপডেট দেখুন]। ডিবাগিং প্রক্রিয়াটিও কোনও পিকনিক নয়, কারণ ত্রুটি বার্তাগুলি প্রায়শই গুপ্ত থাকে, বিশেষত ভিজ্যুয়াল স্টুডিওর ডিজাইন মোড / এক্সপ্রেশন মিশ্রণে।

এটি বলার অপেক্ষা রাখে না যে বিকল্প - সমস্ত মান রূপান্তরগুলির জন্য দর্শন মডেলকে দায়ী করা - এটি একটি উন্নতি। এটি খুব ভাল অন্যদিকে ঘাস সবুজ হয়ে উঠার বিষয় হতে পারে। উদ্বেগগুলির মার্জিত বিভাজনটি হারাতে ছাড়াও, আপনাকে উত্পন্ন বৈশিষ্ট্যগুলির একটি গুচ্ছ লিখতে হবে এবং RaisePropertyChanged(() => DerivedProperty)বেস বৈশিষ্ট্য নির্ধারণের সময় আপনি আন্তরিকতার সাথে কল করতে হবে, যা কোনও অপ্রীতিকর রক্ষণাবেক্ষণের সমস্যা হিসাবে প্রমাণিত হতে পারে।

নীচেরটি আমি ভিউ মডেলগুলিকে রূপান্তর যুক্তি পরিচালনা করতে এবং মান রূপান্তরকারীদের থেকে দূরে সরিয়ে দেওয়ার মুনাফা ও বিবাদগুলি একসাথে রেখেছি:

  • পেশাদাররা:
    • মাল্টি-রূপান্তরকারীগুলি অপসারণের পরে কম মোট বাইন্ডিংগুলি
    • কম যাদু স্ট্রিং (বাঁধাই পথ + রূপান্তরকারী সংস্থার নাম )
    • প্রতিটি রূপান্তরকারী আর রেজিস্ট্রেশন (প্লাস এই তালিকা বজায় রাখা)
    • প্রতিটি রূপান্তরকারী লিখতে কম কাজ (কোন প্রয়োগকারী ইন্টারফেস বা ingালাই প্রয়োজন)
    • রূপান্তরগুলির সাহায্যে সহজে নির্ভরতা ইনজেক্ট করতে পারে (উদাহরণস্বরূপ, রঙের টেবিলগুলি)
    • এক্সএএমএল মার্কআপটি কম ভার্বোস এবং পড়া সহজ
    • রূপান্তরকারী পুনরায় ব্যবহার এখনও সম্ভব (যদিও কিছু পরিকল্পনা প্রয়োজন)
    • DependencyProperty.Unset (রহস্যজনক সমস্যাগুলির সাথে মাল্টি-ভ্যালু রূপান্তরকারীগুলির সাথে আমি লক্ষ্য করেছি)

* স্ট্রাইকথ্রুগুলি এমন সুবিধাগুলি নির্দেশ করে যা আপনি মার্কআপ এক্সটেনশনগুলি ব্যবহার করলে অদৃশ্য হয়ে যায় (নীচে আপডেট দেখুন)

  • কনস:
    • ভিউ মডেল এবং দর্শনগুলির মধ্যে শক্তিশালী সংযোগ (উদাহরণস্বরূপ, বৈশিষ্ট্যগুলি অবশ্যই দৃশ্যমানতা এবং ব্রাশের মতো ধারণাগুলি নিয়ে কাজ করবে)
    • প্রতিটি বাঁধাইয়ের জন্য প্রত্যক্ষ ম্যাপিংয়ের অনুমতি দেওয়ার জন্য আরও মোট সম্পত্তি
    • RaisePropertyChangedপ্রতিটি উত্পন্ন সম্পত্তি জন্য কল করা আবশ্যক (নীচে আপডেট 2 দেখুন)
    • রূপান্তরটি কোনও ইউআই উপাদানের সংস্থার উপর নির্ভর করে এখনও রূপান্তরকারীদের উপর নির্ভর করতে হবে

সুতরাং, আপনি সম্ভবত বলতে পারেন, এই সমস্যাটি নিয়ে আমার কিছুটা জ্বলজ্বল রয়েছে। আমি কেবল রিফ্যাক্টরিংয়ের রাস্তায় যেতে খুব দ্বিধাগ্রস্থ হয়েছি যে কোডিং প্রক্রিয়াটি ঠিক ততটাই অদক্ষ ও ক্লান্তিকর যে আমি মান রূপান্তরকারী ব্যবহার করি বা আমার ভিউ মডেলে অসংখ্য মান রূপান্তর বৈশিষ্ট্য প্রকাশ করি।

আমি কি কোনও উপকার / ধারণা অনুভব করছি? যাঁরা উভয়ই মান রূপান্তরকরণের মাধ্যম চেষ্টা করেছেন, কোনটি আপনার পক্ষে আরও ভাল কাজ করেছে এবং কেন? অন্য কোন বিকল্প আছে? (শিষ্যরা টাইপ বর্ণনাকারী সরবরাহকারীদের সম্পর্কে কিছু উল্লেখ করেছিলেন, তবে তারা কী বলছে সে সম্পর্কে আমি কোনও হ্যান্ডেল পাইনি this এ সম্পর্কে কোনও অন্তর্দৃষ্টি প্রশংসিত হবে))


হালনাগাদ

আমি আজ খুঁজে পেয়েছি যে মান রূপান্তরকারীগুলির নিবন্ধকরণের প্রয়োজনীয়তা নির্ধারণের জন্য "মার্কআপ এক্সটেনশন" নামক কিছু ব্যবহার করা সম্ভব। প্রকৃতপক্ষে, এটি কেবল তাদের নিবন্ধকরণের প্রয়োজনকেই দূর করে না, তবে এটি টাইপ করার সময় এটি রূপান্তরকারী নির্বাচনের জন্য প্রকৃতপক্ষে ইন্টেলিজেন্স সরবরাহ করে Converter=। এখানে আমার নিবন্ধটি শুরু হয়েছে: http://www.wpftutorial.net/ValueConverters.html

মার্কআপ এক্সটেনশানটি ব্যবহারের দক্ষতা আমার উপকার ও বিবাদী তালিকা এবং উপরে আলোচনার কিছুটা ভারসাম্যকে পরিবর্তন করে (স্ট্রাইকথ্রুগুলি দেখুন)।

এই প্রকাশের ফলস্বরূপ, আমি একটি হাইব্রিড সিস্টেমের সাথে পরীক্ষা করছি যেখানে আমি রূপান্তরকারীগুলি ব্যবহার করি BoolToVisibilityএবং আমি যা কল করি MatchToVisibilityএবং অন্যান্য সমস্ত রূপান্তরগুলির জন্য ভিউ মডেলটি ব্যবহার করি। ম্যাচটোভিজিবিলিটি মূলত একটি রূপান্তরকারী যা আমাকে পরীক্ষা করতে দেয় যে সীমাবদ্ধ মানটি (সাধারণত একটি এনাম) এক্সএএমএল-তে নির্দিষ্ট এক বা একাধিক মানের সাথে মেলে কিনা।

উদাহরণ:

Visibility="{Binding Status, Converter={vc:MatchToVisibility
            IfTrue=Visible, IfFalse=Hidden, Value1=Finished, Value2=Canceled}}"

মূলত এটি যা করে তা হ'ল স্থিতিটি শেষ বা বাতিল হয়েছে কিনা তা পরীক্ষা করা। যদি তা হয়, তবে দৃশ্যমানতাটি "দৃশ্যমান" এ সেট হয়ে যায়। অন্যথায়, এটি "গোপনে" সেট হয়ে যায়। এটি একটি খুব সাধারণ দৃশ্যে পরিণত হয়েছিল এবং এই রূপান্তরকারীটি আমার ভিউ মডেলটিতে প্রায় 15 টি সম্পত্তি সংরক্ষণ করেছে (প্লাস সম্পর্কিত RaisePropertyChanged বিবৃতি)। মনে রাখবেন যে আপনি যখন টাইপ করবেন Converter={vc:, তখন "ম্যাচটোভিজিবিলিটি" একটি ইন্টেলিজেন্স মেনুতে প্রদর্শিত হবে। এটি লক্ষণীয়ভাবে ত্রুটির সম্ভাবনা হ্রাস করে এবং মান রূপান্তরকারীগুলিকে কম ক্লান্তিকর করে তোলে (আপনি যে মান রূপান্তর চান তার নামটি মনে রাখতে বা সন্ধান করতে হবে না)।

আপনি যদি কৌতূহলী হন তবে আমি নীচের কোডটি পেস্ট করব। এই বাস্তবায়ন এক গুরুত্বপূর্ণ বৈশিষ্ট্য MatchToVisibilityএটি যদি বাউন্ড মান একটি কিনা দেখতে পরীক্ষা হয় enum, এবং যদি তা না হয়, এটা চেক নিশ্চিত করতে Value1, Value2ইত্যাদি এছাড়াও একই ধরণের enums হয়। এটি এনামের কোনও মান ভুল টাইপ করে কিনা তা একটি ডিজাইন-সময় এবং রান-টাইম চেক সরবরাহ করে। এটি একটি সংকলন-সময় চেক করতে উন্নত করতে, আপনি পরিবর্তে নিম্নলিখিতটি ব্যবহার করতে পারেন (আমি এটি হাত দ্বারা টাইপ করেছি তাই আমি যদি কোনও ভুল হয়ে থাকে তবে আমাকে ক্ষমা করুন):

Visibility="{Binding Status, Converter={vc:MatchToVisibility
            IfTrue={x:Type {win:Visibility.Visible}},
            IfFalse={x:Type {win:Visibility.Hidden}},
            Value1={x:Type {enum:Status.Finished}},
            Value2={x:Type {enum:Status.Canceled}}"

যদিও এটি নিরাপদ, এটি আমার পক্ষে উপযুক্ত হওয়ার পক্ষে খুব ভার্জোজ ver আমি কেবল ভিউ মডেলের একটি সম্পত্তি ব্যবহার করতে পারি যদি আমি এটি করতে যাচ্ছি। যাইহোক, আমি খুঁজে পেয়েছি যে ডিজাইন-সময় চেকটি আমি এ পর্যন্ত চেষ্টা করেছি এমন দৃশ্যের জন্য পুরোপুরি পর্যাপ্ত।

এখানে কোড MatchToVisibility

[ValueConversion(typeof(object), typeof(Visibility))]
public class MatchToVisibility : BaseValueConverter
{
    [ConstructorArgument("ifTrue")]
    public object IfTrue { get; set; }

    [ConstructorArgument("ifFalse")]
    public object IfFalse { get; set; }

    [ConstructorArgument("value1")]
    public object Value1 { get; set; }

    [ConstructorArgument("value2")]
    public object Value2 { get; set; }

    [ConstructorArgument("value3")]
    public object Value3 { get; set; }

    [ConstructorArgument("value4")]
    public object Value4 { get; set; }

    [ConstructorArgument("value5")]
    public object Value5 { get; set; }

    public MatchToVisibility() { }

    public MatchToVisibility(
        object ifTrue, object ifFalse,
        object value1, object value2 = null, object value3 = null,
        object value4 = null, object value5 = null)
    {
        IfTrue = ifTrue;
        IfFalse = ifFalse;
        Value1 = value1;
        Value2 = value2;
        Value3 = value3;
        Value4 = value4;
        Value5 = value5;
    }

    public override object Convert(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        var ifTrue = IfTrue.ToString().ToEnum<Visibility>();
        var ifFalse = IfFalse.ToString().ToEnum<Visibility>();
        var values = new[] { Value1, Value2, Value3, Value4, Value5 };
        var valueStrings = values.Cast<string>();
        bool isMatch;
        if (Enum.IsDefined(value.GetType(), value))
        {
            var valueEnums = valueStrings.Select(vs => vs == null ? null : Enum.Parse(value.GetType(), vs));
            isMatch = valueEnums.ToList().Contains(value);
        }
        else
            isMatch = valueStrings.Contains(value.ToString());
        return isMatch ? ifTrue : ifFalse;
    }
}

এখানে কোড BaseValueConverter

// this is how the markup extension capability gets wired up
public abstract class BaseValueConverter : MarkupExtension, IValueConverter
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }

    public abstract object Convert(
        object value, Type targetType, object parameter, CultureInfo culture);

    public virtual object ConvertBack(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

এখানে ToEnum এক্সটেনশন পদ্ধতি

public static TEnum ToEnum<TEnum>(this string text)
{
    return (TEnum)Enum.Parse(typeof(TEnum), text);
}

আপডেট 2

যেহেতু আমি এই প্রশ্নটি পোস্ট করেছি, আমি একটি মুক্ত-উত্স প্রকল্প জুড়ে এসেছি যা বৈশিষ্ট্য এবং নির্ভরশীল সম্পত্তিগুলির জন্য নোটিফাইপ্রোপার্টি চেঞ্জড কোড ইনজেক্ট করতে "আইএল বয়ন" ব্যবহার করে। এটি "স্টেরয়েডগুলিতে মান রূপান্তরকারী" হিসাবে দর্শনের মডেলটির জোশ স্মিথের দৃষ্টি বাস্তবায়নকে পরম বাতাসে পরিণত করে। আপনি কেবল "অটো-ইমপ্লিমেন্টেড প্রোপার্টি" ব্যবহার করতে পারেন, এবং তাঁতীরা বাকী কাজটি করবেন।

উদাহরণ:

আমি যদি এই কোডটি প্রবেশ করি:

public string GivenName { get; set; }
public string FamilyName { get; set; }

public string FullName
{
    get
    {
        return string.Format("{0} {1}", GivenName, FamilyName);
    }
}

... এটিই সংকলিত হয়:

string givenNames;
public string GivenNames
{
    get { return givenName; }
    set
    {
        if (value != givenName)
        {
            givenNames = value;
            OnPropertyChanged("GivenName");
            OnPropertyChanged("FullName");
        }
    }
}

string familyName;
public string FamilyName
{
    get { return familyName; }
    set 
    {
        if (value != familyName)
        {
            familyName = value;
            OnPropertyChanged("FamilyName");
            OnPropertyChanged("FullName");
        }
    }
}

public string FullName
{
    get
    {
        return string.Format("{0} {1}", GivenName, FamilyName);
    }
}

আপনাকে কোড টাইপ করতে, পড়তে হবে, অতীতে স্ক্রোল করতে হবে ইত্যাদি পরিমাণে এটি একটি বিশাল সঞ্চয় More আরও গুরুত্বপূর্ণ, যদিও এটি আপনাকে আপনার নির্ভরতাগুলি কী তা নির্ধারণ করতে বাঁচায়। FullNameশ্রমসাধ্যভাবে RaisePropertyChanged()কলগুলিতে যোগ করার জন্য নির্ভরতার শৃঙ্খলে না গিয়ে আপনি নতুন "সম্পত্তি পেয়ে" যুক্ত করতে পারেন ।

এই উন্মুক্ত উত্স প্রকল্পটি কী বলা হয়? আসল সংস্করণটিকে বলা হয় "নোটিফাইপ্রোপার্টিওয়েভার", তবে এর পরে মালিক (সাইমন পটার) আইএল তাঁতিদের পুরো সিরিজের হোস্টিংয়ের জন্য "ফডি" নামে একটি প্ল্যাটফর্ম তৈরি করেছেন। এই নতুন প্ল্যাটফর্মের অধীনে নোটিফাইপার্টিভিয়ারের সমতুল্যকে প্রপার্টি চেঞ্জড.ফডি বলা হয়।

আপনি যদি NotifyPropertyWeaver (যা ইনস্টল করতে কিছুটা সহজ, তবে ভবিষ্যতে বাগ ফিক্সের বাইরেও আপডেট হওয়া প্রয়োজন না) নিয়ে যেতে পছন্দ করেন, এখানে প্রকল্প সাইটটি: http://code.google.com/p/ notifypropertyweaver /

যে কোনও উপায়ে, এই আইএল তাঁত সমাধানগুলি স্টেরয়েড বনাম মান রূপান্তরকারীগুলিতে ভিউ মডেলের মধ্যে বিতর্কে ক্যালকুলাসকে সম্পূর্ণ পরিবর্তন করে change


কেবল একটি নোট: BooleanToVisibilityদৃশ্যমানতার সাথে সম্পর্কিত এমন একটি মান নেয় (সত্য / মিথ্যা) এবং এটিকে অন্য একটিতে অনুবাদ করে। এটি একটি আদর্শ ব্যবহারের মতো বলে মনে হচ্ছে ValueConverter। অন্যদিকে, (কী ধরণের আইটেমগুলি দৃশ্যমান হওয়া উচিত) এ MatchToVisibilityব্যবসার যুক্তিটিকে এনকোডিং করছে View। আমার মতে এই যুক্তিটি নীচে চাপানো উচিত ViewModel, বা আরও যেদিকে আমি ডাকে EditModel। ব্যবহারকারী যা দেখতে পাবে তা পরীক্ষার অধীনে থাকা উচিত।
স্কট হুইটলক

@ স্কট, এটি একটি ভাল বিষয়। আমি এখনই যে অ্যাপটি নিয়ে কাজ করছি তা আসলে কোনও "ব্যবসায়" অ্যাপ্লিকেশন নয়, যেখানে ব্যবহারকারীদের জন্য বিভিন্ন অনুমতি স্তর রয়েছে, তাই আমি এই লাইনগুলি নিয়ে ভাবছিলাম না। MatchToVisibilityকিছু সাধারণ মোড স্যুইচ সক্ষম করার সুবিধাজনক উপায় বলে মনে হয়েছিল (আমার বিশেষত একটি ভিউ রয়েছে যা অনেকগুলি অংশের সাথে চালু এবং বন্ধ করা যায় most বেশিরভাগ ক্ষেত্রে, ভিউটির অংশগুলি x:Nameমোডের সাথে মেলে এমনকি লেবেলযুক্ত থাকে ) তারা এর সাথে সঙ্গতি বোধ করে।) এটি আমার কাছে সত্যই ঘটেনি যে এটি "ব্যবসায়িক যুক্তি", তবে আমি আপনার মন্তব্যটি কিছু চিন্তাভাবনা করব।
ডিভাক্সার

উদাহরণ: বলুন আপনার কাছে একটি স্টেরিও সিস্টেম ছিল যা হয় রেডিও, সিডি বা এমপি 3 মোডে থাকতে পারে। ধরে নিন ইউআই এর বিভিন্ন অংশে প্রতিটি মোডের সাথে সম্পর্কিত ভিজ্যুয়াল রয়েছে। আপনি হয় (১) কোন গ্রাফিক্সটি কোন মোডের সাথে সামঞ্জস্য করে এবং সেই অনুযায়ী সেগুলি চালু / বন্ধ করে দেওয়া উচিত (2) প্রতিটি মোডের মান (উদাহরণস্বরূপ, ইসমোডেরাদিয়ো, ইসমোডিসিডি) বা ভিউ মডেলটিতে (3) এক্সপোজ করা উচিত প্রতিটি গ্রাফিকাল উপাদান / গোষ্ঠী (উদাহরণস্বরূপ, IsRadioLightOn, IsCDButtonGroupOn) এর জন্য ভিউ মডেলের বৈশিষ্ট্য। (1) আমার দৃষ্টিতে প্রাকৃতিক ফিট বলে মনে হয়েছিল, কারণ এতে ইতিমধ্যে সচেতনতা রয়েছে। এক্ষেত্রে আপনার কী ধারণা?
ডিভাক্সার

এটি দীর্ঘতম প্রশ্ন, আমি কখনও পুরো এসইতে দেখেছি! :]
ট্রেজার্ডার

উত্তর:


10

আমি ValueConvertersকিছু ক্ষেত্রে ব্যবহার করেছি এবং যুক্তি ViewModelঅন্যদের মধ্যে রেখেছি । আমার অনুভূতিটি হ'ল একটি স্তরটির ValueConverterঅংশ হয়ে যায় View, সুতরাং যদি যুক্তিটি সত্যই এর অংশ হয় Viewতবে এটি সেখানে রাখুন, অন্যথায় এটিতে রাখুন ViewModel

ব্যক্তিগতভাবে আমি এস-এর মতো-স্পেসিফিক ধারণাগুলির ViewModelসাথে কাজ করার ক্ষেত্রে কোনও সমস্যা দেখি না কারণ আমার অ্যাপ্লিকেশনগুলিতে কেবলমাত্র পরীক্ষার যোগ্য এবং বাইন্ডিয়েবল পৃষ্ঠ হিসাবে বিদ্যমান । যাইহোক, কিছু লোক (আমি করি না) প্রচুর ব্যবসায়িক যুক্তি রেখেছি এবং সেক্ষেত্রে বিষয়টি তাদের ব্যবসায়ের স্তরের অংশের মতো, সুতরাং সেই ক্ষেত্রে আমি সেখানে ডাব্লুপিএফ-নির্দিষ্ট জিনিস চাই না।ViewBrushViewModelViewViewModelViewModel

আমি আলাদা বিচ্ছেদ পছন্দ করি:

  • View- ডাব্লুপিএফ স্টাফ, কখনও কখনও অকেটেস্টেবল (এক্সএএমএল এবং কোড-পিছনের মতো) তবে ValueConverters
  • ViewModel - টেস্টেবল এবং বাইন্ডেবল ক্লাস যা ডাব্লুপিএফ-নির্দিষ্ট
  • EditModel - ব্যবসায়ের স্তরের অংশ যা হেরফেরের সময় আমার মডেলকে উপস্থাপন করে
  • EntityModel - ব্যবসায়ের স্তরের অংশ যা আমার মডেলটিকে স্থির হিসাবে উপস্থাপন করে
  • Repository- EntityModelডাটাবেস থেকে অধ্যবসায় জন্য দায়ী

সুতরাং, আমি যেভাবে এটি করি, ValueConverterএস এর জন্য আমার খুব কম ব্যবহার

আপনার "কনসের" থেকে যেভাবে আমি দূরে সরে এসেছি তা হল আমার ViewModelখুব জেনেরিক। উদাহরণস্বরূপ, ViewModelআমার কাছে একটি, ChangeValueViewModelএকটি লেবেল সম্পত্তি এবং একটি মান সম্পত্তি প্রয়োগ করে। উপর Viewএকটা ব্যাপার Labelসেই লেবেল সম্পত্তিতে binds এবং একটি TextBoxযে মান সম্পত্তিতে শুশ্রূষা।

আমি তখন একটি ChangeValueViewযা টাইপ একটি DataTemplatekeyed বন্ধ আছে ChangeValueViewModel। ডাব্লুপিএফ যখনই দেখে যে ViewModelএটি এটি প্রয়োগ করে View। আমার কনস্ট্রাক্টর ChangeValueViewModelইন্টারঅ্যাকশন যুক্তিটি গ্রহণ করে যা এটির থেকে তার অবস্থা EditModel(সাধারণত কেবলমাত্র একটি মধ্যে চলে যাওয়া Func<string>) থেকে রিফ্রেশ করতে হবে এবং ব্যবহারকারী যখন মান সম্পাদনা করে তখন এটি গ্রহণ করা প্রয়োজনীয় পদক্ষেপ (কেবল একটি Actionযা কিছু যুক্তিকে কার্যকর করে EditModel)।

পিতা-মাতা ViewModel(পর্দার জন্য) এর নির্মাতার মধ্যে একটি নেয় EditModelএবং কেবলমাত্র উপযুক্ত প্রাথমিকগুলি ViewModelযেমন ইনস্ট্যান্ট করে ChangeValueViewModel। যেহেতু ViewModelঅভিভাবকরা ব্যবহারকারী কোনও পরিবর্তন আনার সময় পদক্ষেপ নেওয়ার জন্য ইনজেকশন দিচ্ছেন, তাই এটি এই সমস্ত ক্রিয়াকে বিরত রাখতে এবং অন্যান্য পদক্ষেপ নিতে পারে। অতএব, ইনজেকশনের সম্পাদনা ক্রিয়াকলাপটি এর ChangeValueViewModelমতো দেখতে পাওয়া যায়:

(string newValue) =>
{
    editModel.SomeField = newValue;
    foreach(var childViewModel in this.childViewModels)
    {
        childViewModel.RefreshStateFromEditModel();
    }
}

স্পষ্টতই foreachলুপটি অন্য কোথাও রিফ্যাক্টর করা যেতে পারে, তবে এটি যা করণীয় তা মডেলটিতে প্রয়োগ করুন, তারপরে (ধরে নিলেন মডেলটি কোনও অজানা উপায়ে তার রাজ্য আপডেট করেছে), সমস্ত শিশুকে বলে ViewModelএবং তাদের অবস্থা থেকে ফিরে যেতে আবার মডেল। যদি রাষ্ট্রটি পরিবর্তিত হয় তবে তারা PropertyChangedপ্রয়োজনীয় তাদের ইভেন্টগুলি সম্পাদনের জন্য দায়বদ্ধ ।

এটি বেশ সুন্দরভাবে একটি তালিকা বাক্স এবং বিশদ প্যানেলের মধ্যে কথোপকথন পরিচালনা করে। যখন ব্যবহারকারী কোনও নতুন পছন্দ বাছাই করে, এটি পছন্দ EditModelসহ আপডেটগুলি আপডেট করে এবং EditModelবিশদ প্যানেলের জন্য প্রকাশিত বৈশিষ্ট্যের মান পরিবর্তন করে। ViewModelশিশুদের যে বিস্তারিত প্যানেল তথ্য স্বয়ংক্রিয়ভাবে জানানো যে, তারা নতুন মান পরীক্ষা করার জন্য প্রয়োজন, এবং যদি তারা পরিবর্তন করেছি, তারা তাদের আগুন প্রদর্শন করার জন্য দায়ী PropertyChangedইভেন্ট নেই।


/ নড়া। এটা আমার চেহারা দেখতে অনুরূপ।
আয়ান

+1 টি। আপনার উত্তরের জন্য ধন্যবাদ, স্কট, আমি আপনার মত একই স্তরগুলি প্রায় পেয়েছি এবং আমি ভিউ মডেলটিতে ব্যবসায়িক যুক্তিও রাখি না। (রেকর্ডের জন্য, আমি প্রথমে এন্টি ফ্রেমওয়ার্ক কোড ব্যবহার করছি, এবং আমার কাছে একটি পরিষেবা স্তর রয়েছে যা ভিউ মডেল এবং সত্তার মডেলগুলির মধ্যে অনুবাদ করে, এবং তদ্বিপরীত given ভিউ মডেল স্তরে সমস্ত / বেশিরভাগ রূপান্তর যুক্তিকে যুক্ত করতে।
ডেভুসার

@ ড্যানএম - হ্যাঁ, আমি সম্মত। আমি ViewModelস্তরটিতে রূপান্তরটি পছন্দ করব । সবাই আমার সাথে একমত নয়, তবে এটি আপনার আর্কিটেকচারটি কীভাবে কাজ করে তার উপর নির্ভর করে।
স্কট হুইটলক

2
আমি প্রথম অনুচ্ছেদটি পড়ার পরে +1 বলতে যাচ্ছিলাম, কিন্তু তারপরে আমি আপনার ২ য় নম্বরটি পড়েছি এবং ভিউমোডেলগুলিতে ভিউ-সুনির্দিষ্ট কোড স্থাপনের সাথে দৃ strongly়ভাবে একমত নই। একটি ব্যতিক্রম হ'ল যদি ভিউমোডেলটি জেনেরিক ভিউ (যেমন ইউজারকন্ট্রোলের CalendarViewModelজন্য একটি CalendarView, বা একটির DialogViewModelজন্য DialogView) এর পিছনে যাওয়ার জন্য বিশেষভাবে তৈরি করা হয় । যদিও এটি আমার মতামত :)
রাচেল

@ রাচেল - আচ্ছা, আপনি যদি আমার দ্বিতীয় অনুচ্ছেদে অতীতে পড়া চালিয়ে যান তবে আপনি দেখতে পাবেন যে আমি ঠিক তাই করছিলাম। :) আমার কোন ব্যবসায়িক যুক্তি নেই ViewModel
স্কট হুইটলক

8

রূপান্তরটি যদি ভিউ-রিলেটেড কিছু হয় যেমন কোনও বস্তুর দৃশ্যমানতা সিদ্ধান্ত নেওয়া, কোন চিত্রটি প্রদর্শিত হবে তা নির্ধারণ করা বা কোন ব্রাশের রঙ ব্যবহার করতে হবে তা নির্ধারণ করা, আমি সর্বদা আমার রূপান্তরকারীকে ভিউতে রাখি।

যদি এর ব্যবসায়ের সাথে সম্পর্কিত, যেমন কোনও ক্ষেত্রটি মাস্ক করা উচিত কিনা তা নির্ধারণ করা বা কোনও ব্যবহারকারীর কোনও ক্রিয়া সম্পাদনের অনুমতি থাকলে, তাহলে রূপান্তরটি আমার ভিউমোডেলে ঘটে।

আপনার উদাহরণ থেকে, আমার মনে হয় আপনি WPF একটি বড় টুকরা অনুপস্থিত: DataTriggers। শর্তসাপেক্ষ মানগুলি নির্ধারণের জন্য আপনি রূপান্তরকারী ব্যবহার করছেন বলে মনে হয়, তবে রূপান্তরকারীরা একটি ডেটা টাইপকে অন্যটিতে রূপান্তর করার জন্য সত্যই হওয়া উচিত।

উপরে আপনার উদাহরণে

উদাহরণ: বলুন আপনার কাছে একটি স্টেরিও সিস্টেম ছিল যা হয় রেডিও, সিডি বা এমপি 3 মোডে থাকতে পারে। ধরে নিন ইউআই এর বিভিন্ন অংশে প্রতিটি মোডের সাথে সম্পর্কিত ভিজ্যুয়াল রয়েছে। আপনি হয় (১) কোন গ্রাফিক্সটি কোন মোডের সাথে সামঞ্জস্য করে এবং সেই অনুযায়ী সেগুলি চালু / বন্ধ করে দেওয়া উচিত (2) প্রতিটি মোডের মান (উদাহরণস্বরূপ, ইসমোডেরাদিয়ো, ইসমোডিসিডি) বা ভিউ মডেলটিতে (3) এক্সপোজ করা উচিত প্রতিটি গ্রাফিকাল উপাদান / গোষ্ঠী (উদাহরণস্বরূপ, IsRadioLightOn, IsCDButtonGroupOn) এর জন্য ভিউ মডেলের বৈশিষ্ট্য। (1) আমার দৃষ্টিতে একটি প্রাকৃতিক ফিট বলে মনে হয়েছিল, কারণ এতে ইতিমধ্যে সচেতনতা রয়েছে has এক্ষেত্রে আপনার কী ধারণা?

DataTriggerকোনটি প্রদর্শিত হবে তা নির্ধারণ করতে আমি একটি ব্যবহার করব, একটি নয় Converter। একটি রূপান্তরকারী একটি ডেটা টাইপকে অন্যটিতে রূপান্তর করার জন্য হয়, যখন একটি ট্রিগার ব্যবহার করা হয় একটি মানের উপর ভিত্তি করে কিছু বৈশিষ্ট্য নির্ধারণ করতে।

<Style x:Key="RadioImageStyle">
    <Setter Property="Source" Value="{StaticResource RadioImage}" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding Mode}" Value="CD">
            <Setter Property="Source" Value="{StaticResource CDImage}" />
        </DataTrigger>
        <DataTrigger Binding="{Binding Mode}" Value="MP3">
            <Setter Property="Source" Value="{StaticResource MP3Image}" />
        </DataTrigger>
    </Style.Triggers>
</Style>

আমি কেবলমাত্র এটির জন্য একটি কনভার্টার ব্যবহার করার বিষয়টি বিবেচনা করব যদি সীমাবদ্ধ মানটিতে চিত্রের ডেটা থাকে এবং আমি এটি ইউআই বুঝতে পারে এমন একটি ডেটা ধরণের রূপান্তরিত করতে চাই। উদাহরণস্বরূপ, যদি ডেটা উত্সটিতে কোনও সম্পত্তি হিসাবে ডাকা হয় ImageFilePathতবে আমি চিত্রের ফাইলের অবস্থান সম্বলিত স্ট্রিংটিকে এমন একটি রূপান্তর করতে কনভার্টর ব্যবহার করে বিবেচনা করব BitmapImageযা আমার চিত্রের উত্স হিসাবে ব্যবহার করা যেতে পারে

<Style x:Key="RadioImageStyle">
    <Setter Property="Source" Value="{Binding ImageFilePath, 
            Converter={StaticResource StringPathToBitmapConverter}}" />
</Style>

শেষ ফলাফলটি হ'ল আমার কাছে একটি লাইব্রেরির নেমস্পেস জেনেরিক রূপান্তরকারী পূর্ণ যা একটি তথ্য টাইপকে অন্যটিতে রূপান্তরিত করে, এবং আমার খুব কমই একটি নতুন রূপান্তরকারী কোড করতে হয়। এমন কিছু অনুষ্ঠান আছে যখন আমি নির্দিষ্ট রূপান্তরগুলির জন্য রূপান্তরকারীদের চাইব, তবে এগুলি এতটা বিরল যে এগুলি লিখতে আমার কখনও আপত্তি নেই।


+1 টি। আপনি কিছু ভাল পয়েন্ট উত্থাপন। আমি এর আগে ট্রিগার ব্যবহার করেছি, তবে আমার ক্ষেত্রে আমি চিত্রগুলির উত্সগুলি (যা একটি সম্পত্তি) স্যুইচ আউট করছি না, আমি সম্পূর্ণ Gridউপাদানগুলি স্যুইচ করছি । আমি আমার ভিউ মডেলের ডেটা এবং কনফিগার ফাইলে সংজ্ঞায়িত একটি নির্দিষ্ট রঙ প্যালেট ভিত্তিক ফোরগ্রাউন্ড / ব্যাকগ্রাউন্ড / স্ট্রোকের জন্য সেট ব্রাশের মতো জিনিসগুলি করার চেষ্টা করছি। আমি নিশ্চিত না যে এটি ট্রিগার বা রূপান্তরকারী উভয়ের জন্যই দুর্দান্ত ফিট। ভিউ মডেলটিতে সর্বাধিক দেখার যুক্তি যুক্ত করার সাথে আমার এখন পর্যন্ত কেবলমাত্র সমস্যাটিই হ'ল সমস্ত RaisePropertyChanged()কলকে ওয়্যার আপ করে দিচ্ছে ।
ডিভাক্সার

@ ড্যানএম আমি আসলে DataTriggerগ্রিডের উপাদানগুলিকে স্যুইচ করে এগুলিতে সমস্ত কিছু করতে চাই । সাধারণত আমি এমন স্থানে ContentControlরাখি যেখানে আমার গতিশীল বিষয়বস্তু হওয়া উচিত এবং ট্রিগারটিতে এটিকে সরিয়ে আনা হবে ContentTemplate। আপনি যদি আগ্রহী হন তবে নীচের লিঙ্কটিতে আমার একটি উদাহরণ রয়েছে (হেডারের সাথে বিভাগে স্ক্রোল করুন Using a DataTrigger) rachel53461.wordpress.com/2011/05/28/…
রাচেল

আমি এর আগে ডেটা টেম্পলেট এবং সামগ্রী নিয়ন্ত্রণ ব্যবহার করেছি তবে আমার কখনই ট্রিগার দরকার হয়নি কারণ প্রতিটি দৃশ্যের জন্য আমার কাছে সর্বদা একটি অনন্য ভিউ মডেল ছিল। যাইহোক, আপনার কৌশলটি নিখুঁত ধারণা তৈরি করে এবং বেশ মার্জিত, তবে এটি খুব ভার্জোজ। ম্যাচটোভিজিবিলিটি সহ এটি এটি সংক্ষিপ্ত করা যেতে পারে:<TextBlock Text="I'm a Person" Visibility={Binding ConsumerType, Converter={vc:MatchToVisibility IfTrue=Visible, IfFalse=Hidden, Value1=Person}}" এবং<TextBlock Text="I'm a Business" Visibility={Binding ConsumerType, Converter={vc:MatchToVisibility IfTrue=Visible, IfFalse=Hidden, Value1=Business}}"
ডিভুসার

1

এটি আপনি যা পরীক্ষা করছেন তার উপর নির্ভর করে যদি কিছু হয়।

কোনও পরীক্ষা নেই: ইন্টিমিক্স দেখুন কোড ডাব্লু / ভিউমোডেল (আপনি সর্বদা পরে রিফেক্টর করতে পারেন)।
ভিউমোডেল এবং / বা তার চেয়ে কম টেস্ট: রূপান্তরকারী ব্যবহার করুন।
মডেল স্তরগুলি এবং / বা তার চেয়ে নিম্নের পরীক্ষাগুলি: ইন্টিমিক্স উইড কোড / ডাব্লু / ভিডমোডেল উইলে

ভিউমোডেল ভিউর জন্য মডেলটিকে বিমূর্ত করে । ব্যক্তিগতভাবে, আমি ব্রাশ ইত্যাদির জন্য ভিউমোডেল ব্যবহার করব এবং রূপান্তরকারীগুলি এড়িয়ে যাব। টেস্ট স্তরে (গুলি) যেখানে ডাটা তার " বিশুদ্ধতম " ফর্মটিতে (যেমন মডেল স্তরগুলি ) থাকে।


2
পরীক্ষার বিষয়ে আকর্ষণীয় বিষয়, তবে আমার ধারণা আমি দেখতে পাচ্ছি না যে ভিউ মডেলে রূপান্তরকারী যুক্তিটি কীভাবে ভিউ মডেলের টেস্টিবিলিটির ক্ষতি করে? আমি অবশ্যই ভিউ মডেলটিতে প্রকৃত ইউআই নিয়ন্ত্রণ রাখার পরামর্শ দিচ্ছি না । শুধু দেখতে-নির্দিষ্ট বৈশিষ্ট্য পছন্দ Visibility, SolidColorBrushএবং Thickness
ডেভুসার

@ ড্যানএম: আপনি যদি ভিউ-ফার্স্ট পদ্ধতির ব্যবহার করেন তবে কোনও সমস্যা নেই । তবে কেউ কেউ ভিউমোডেল-প্রথম পদ্ধতির ব্যবহার করেন যেখানে ভিউমোডেল একটি দৃশ্যের উল্লেখ করে, এটি সমস্যাযুক্ত হতে পারে ।
জ্যাক বার্গার

হাই জে, অবশ্যই একটি দৃশ্যের প্রথম পদ্ধতির। ভিউ মডেলটি যে গুণাগুলিতে আবদ্ধ হওয়া প্রয়োজন তার নাম বাদে ভিউ মডেল সম্পর্কে কিছুই জানে না। অনুসরণ করার জন্য ধন্যবাদ। +1 টি।
ডেভুসার

0

এটি সম্ভবত আপনার উল্লিখিত সমস্ত সমস্যার সমাধান করবে না, তবে দুটি বিষয় বিবেচনা করতে হবে:

প্রথমত, আপনাকে আপনার প্রথম কৌশলটির মধ্যে কোনও রূপান্তর কোড স্থাপন করা দরকার। আপনি কি ভিউ বা ভিউ মডেলটির সেই অংশটি বিবেচনা করছেন? এটি যদি দেখার অংশ হয় তবে ভিউ-মডেলের পরিবর্তে ভিউ-নির্দিষ্ট বৈশিষ্ট্যগুলিকে কেন ভিউতে রাখবেন না?

দ্বিতীয়ত, আপনার নন-রূপান্তরকারী ডিজাইন ইতিমধ্যে বিদ্যমান প্রকৃত বস্তুর বৈশিষ্ট্যগুলিকে সংশোধন করার চেষ্টা করছে বলে মনে হচ্ছে। দেখে মনে হচ্ছে যে তারা ইতিমধ্যে INotifyPropertyChanged বাস্তবায়ন করেছে, সুতরাং কেন আবদ্ধ করতে একটি ভিউ-নির্দিষ্ট র‌্যাপার অবজেক্ট তৈরি করবেন না? এখানে একটি সাধারণ উদাহরণ:

public class RealData
{
    private bool mIsInteresting;
    public bool IsInteresting
    {
        get { return mIsInteresting; }
        set 
        {
            if (mIsInteresting != null) 
            {
                mIsInteresting = value;
                RaisePropertyChanged("IsInteresting");
            }
        }
    }
}

public class RealDataView
{
    private RealData mRealData;

    public RealDataView(RealData data)
    {
        mRealData = data;
        mRealData.PropertyChanged += OnRealDataPropertyChanged;
    }

    public Visibility IsVisiblyInteresting
    {
       get { return mRealData.IsInteresting ? Visibility.Visible : Visibility.Hidden; }
       set { mRealData.IsInteresting = (value == Visibility.Visible); }
    }

    private void OnRealDataPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "IsInteresting") 
        {
            RaisePropertyChanged(this, "IsVisiblyInteresting");
        }
    }
}

আমি বোঝাতে চাইছি না যে আমি নিজের সত্তা মডেলের বৈশিষ্ট্যগুলি সরাসরি ভিউ বা ভিউ মডেলটিতে পরিবর্তন করছি। ভিউ মডেলটি অবশ্যই আমার সত্তার মডেল স্তরের চেয়ে পৃথক স্তর। আসলে, আমি এখনও পর্যন্ত কাজটি কেবল পঠনযোগ্য দর্শনগুলিতেই করেছি। এটি বলার অপেক্ষা রাখে না যে আমার অ্যাপ্লিকেশনটিতে কোনও সম্পাদনা জড়িত হবে না, তবে আমি সম্পাদনার জন্য ব্যবহৃত নিয়ন্ত্রণগুলিতে কোনও রূপান্তর দেখছি না (সুতরাং ধরে রাখুন তালিকাগুলি বাছাই ব্যতীত সমস্ত বাইন্ডিং একমুখী)। যদিও "ডেটা ভিউ" সম্পর্কে ভাল পয়েন্ট। এটি আমার ধারণার শীর্ষে উল্লেখ করা এক্সএএমএল শিষ্যদের পোস্টে উত্থাপিত একটি ধারণা ছিল।
ডেভুসার

0

কখনও কখনও ভার্চুয়ালাইজেশনের সুবিধা নিতে একটি মান রূপান্তরকারী ব্যবহার করা ভাল।

একটি গ্রিডে কয়েক লক্ষ কোষের জন্য আমাদের বিটমাস্ক ডেটা প্রদর্শন করতে হয়েছিল এমন একটি প্রকল্পের এটির উদাহরণ। যখন আমরা প্রতিটি একক কক্ষের জন্য ভিউ মডেলে বিটমাস্কগুলি ডিকোড করি তখন প্রোগ্রামটি লোড হতে অনেক বেশি সময় নেয়।

কিন্তু যখন আমরা একটি মান রূপান্তরকারী তৈরি করি যা একটি একক কক্ষকে ডিকোড করে সেই সময়ের একটি ভগ্নাংশে প্রোগ্রাম লোড করে এবং ঠিক ততটা প্রতিক্রিয়াশীল কারণ যখন ব্যবহারকারী নির্দিষ্ট কক্ষের দিকে তাকিয়ে থাকে তখন কেবল রূপান্তরকারীকে ডাকা হয় (এবং এটি কেবল কল করার প্রয়োজন হবে) ব্যবহারকারী যখন গ্রিডে তাদের দৃষ্টিভঙ্গি সর্বাধিক ত্রিশ বার করে ফেলেছে)।

আমি জানি না কীভাবে এমভিভিএম অভিযোগ করেছিল যে সমাধানটি ছিল, তবে এটি লোডের সময়টি 95% কেটে নিয়েছিল।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.