এমভিভিএমের সাথে ডাব্লুপিএফ-তে ডায়ালগগুলি পরিচালনা করা


235

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

ডায়লগগুলি থেকে ফলাফলগুলি হ্যান্ডেল করার কোনও ভাল উপায় কি কেউ জানেন? আমি যেমন উইন্ডো ডায়ালগ সম্পর্কে বলছি MessageBox

আমরা এটি করার একটি উপায় ছিল ভিউমডেলের একটি ইভেন্ট যা কোনও সংলাপের প্রয়োজন হলে ভিউটি সাবস্ক্রাইব করবে।

public event EventHandler<MyDeleteArgs> RequiresDeleteDialog;

এটি ঠিক আছে, তবে এর অর্থ হল ভিউটিতে কোডের প্রয়োজন যা এমন কিছু যা আমি দূরে থাকতে চাই।


ভিউতে কোনও সহায়ক অবজেক্টকে কেন আবদ্ধ করবেন না?
পল উইলিয়ামস

1
আপনি কি বোঝাতে চেয়েছেন তা নিশ্চিত না।
রায় বুয়েসন

1
যদি আমি প্রশ্নটি বুঝতে পারি তবে আপনি ভিএম পপ আপ ডায়লগগুলি চান না এবং আপনি ভিউতে কোড-বর্ধিত চান না। তবুও মনে হচ্ছে আপনি ইভেন্টগুলিতে কমান্ড পছন্দ করেন। আমি এই সবগুলির সাথে একমত, তাই আমি ভিউতে একটি সহায়ক শ্রেণি ব্যবহার করি যা ডায়ালগটি পরিচালনা করার জন্য একটি আদেশ প্রকাশ করে। আমি এই প্রশ্নের উত্তর এখানে অন্য থ্রেডে দিয়েছি: stackoverflow.com/a/23303267/420400 । তবে, সর্বশেষ বাক্যটি এটিকে শোনায় যে আপনি ভিউর কোথাও কোনও কোড চান না । আমি সেই উদ্বেগটি বুঝতে পারি তবে প্রশ্নের কোডটি কেবলমাত্র শর্তযুক্ত এবং এটি পরিবর্তিত হওয়ার সম্ভাবনা নেই।
পল উইলিয়ামস

4
থেজে ভিউ মডেলটি সর্বদা ডায়লগ বাক্স তৈরির পিছনে যুক্তির জন্য দায়বদ্ধ হওয়া উচিত, এটিই প্রথম স্থানে তার অস্তিত্বের পুরো কারণ। এটি বলেছে যে ভিউটি তৈরির ক্ষেত্রে এটি উত্তোলন উত্তোলন (এবং করা উচিত নয়)। আমি কোডেপ্রজেক্ট / আর্টিকেলস / ৮২০৩৪ / ২ তে এই বিষয়ে একটি নিবন্ধ লিখেছি যেখানে আমি দেখাই যে ডায়ালগ বাক্সগুলির পুরো জীবনচক্রটি নিয়মিত ডাব্লুপিএফ ডেটা বাইন্ডিংয়ের মাধ্যমে এবং এমভিভিএম প্যাটার্নটি ভঙ্গ না করে পরিচালনা করা যায়।
মার্ক ফিল্ডম্যান

উত্তর:


131

আমি 1990 এর মডেল সংলাপগুলি অগ্রাহ্য করার পরামর্শ দিয়েছি এবং পরিবর্তে ভিএম-তে একটি বুলিয়ানের সাথে দৃশ্যমানতার সাথে ওভারলে (ক্যানভাস + পরম অবস্থান) হিসাবে নিয়ন্ত্রণ প্রয়োগ করার পরামর্শ দিচ্ছি। একটি এজ্যাক্স টাইপ নিয়ন্ত্রণের কাছাকাছি।

এটি খুব দরকারী:

<BooleanToVisibilityConverter x:Key="booltoVis" />

যেমন হিসাবে:

<my:ErrorControl Visibility="{Binding Path=ThereWasAnError, Mode=TwoWay, Converter={StaticResource booltoVis}, UpdateSourceTrigger=PropertyChanged}"/>

আমি এখানে একজন ব্যবহারকারী নিয়ন্ত্রণ হিসাবে কীভাবে প্রয়োগ করেছি। 'এক্স' এ ক্লিক করলে ব্যবহারকারীকন্ট্রোলের কোডের পিছনে কোডের একটি লাইনে নিয়ন্ত্রণ বন্ধ হয়ে যায়। (যেহেতু আমার কাছে একটি ডিসিএলএক্সে এবং ভিউমোডেলগুলিতে আমার ভিউ রয়েছে, তাই ইউআই কে ম্যানিপুলেট করে এমন কোড সম্পর্কে আমি খারাপ মনে করি না))

ডাব্লুপিএফ ডায়ালগ


20
হ্যাঁ, আমি এই ধারণাটিও পছন্দ করি তবে এটি কীভাবে প্রদর্শন করতে হয় এবং এই থেকে সংলাপের ফলাফল পুনরুদ্ধার করা ইত্যাদি ক্ষেত্রে এই নিয়ন্ত্রণের কয়েকটি উদাহরণ দেখতে চাই বিশেষত সিলভারলাইটের এমভিভিএম দৃশ্যে।
রোবব্লব 8'10

16
আপনি কীভাবে এই ডায়ালগ ওভারলে এর নীচে নিয়ন্ত্রণের সাথে ইন্টারঅ্যাক্ট করা থেকে ব্যবহারকারীকে বাধা দেন?
অ্যান্ড্রু গ্যারিসন

16
এই পদ্ধতির সমস্যাটি হ'ল আপনি প্রথমটি থেকে দ্বিতীয় মডেল কথোপকথনটি খুলতে পারবেন না, কমপক্ষে ওভারলে সিস্টেমে কোনও ভারী পরিবর্তন ছাড়াই নয় ...
থমাস লেভস্ক

6
এই পদ্ধতির সাথে আর একটি সমস্যা হ'ল "ডায়লগ" সরানো যায় না। আমাদের অ্যাপ্লিকেশনগুলিতে, আমাদের অবশ্যই একটি চলমান ডায়ালগ থাকা উচিত যাতে ব্যবহারকারী এটির পিছনে কী তা দেখতে পারে।
জ্যাব

12
এই পদ্ধতিটি আমার কাছে ভয়ঙ্কর বলে মনে হচ্ছে। আমি কী মিস করছি? এটি কীভাবে সত্যিকারের ডায়ালগ বক্সের চেয়ে ভাল?
জোনাথন উড

51

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

আপনার গুগল ডাব্লুপিএফ শিষ্য গোষ্ঠীটি পরীক্ষা করা উচিত এবং কেবল মধ্যস্থতাকারীর সন্ধান করা উচিত। উত্তরগুলি দিয়ে আপনি অনেক খুশি হবেন ...

তবে আপনি এটি দিয়ে শুরু করতে পারেন:

http://joshsmithonwpf.wordpress.com/2009/04/06/a-mediator-prototype-for-wpf-apps/

উপভোগ করুন!

সম্পাদনা করুন: আপনি এখানে এমভিভিএম লাইট টুলকিটের সাহায্যে এই সমস্যার উত্তর দেখতে পারেন:

http://mvvmlight.codeplex.com/Thread/View.aspx?ThreadId=209338


2
মারলন গ্রেচ সবেমাত্র মধ্যস্থতাকারীর একদম
2009

21
কেবল একটি মন্তব্য: মধ্যস্থতাকারী প্যাটার্নটি ডাব্লুপিএফ শিষ্যদের দ্বারা প্রবর্তিত হয়নি, এটি একটি ধ্রুপদী জিওএফ প্যাটার্ন ... ( dofactory.com/Patterns/PatternMediator.aspx )। উত্তম উত্তর অন্যথায়;)
টমাস লেভেস্ক

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

34

একটি ভাল এমভিভিএম ডায়ালগের উচিত:

  1. কেবল এক্সএএমএল দিয়ে ঘোষণা করা হবে।
  2. এটির সমস্ত আচরণ ডেটাবাইন্ডিং থেকে পান।

দুর্ভাগ্যক্রমে, ডাব্লুপিএফ এই বৈশিষ্ট্যগুলি সরবরাহ করে না। একটি ডায়ালগ দেখানোর জন্য একটি কোড-পিছনে কল প্রয়োজন ShowDialog()। উইন্ডো শ্রেণি, যা ডায়লগ সমর্থন করে, এক্সএএমএল-তে ঘোষণা করা যায় না তাই এটি সহজেই ডেটাবাউন্ডে যায় না DataContext

এটি সমাধান করার জন্য, আমি একটি এক্সএএমএল স্টাব নিয়ন্ত্রণ লিখেছিলাম যা লজিক্যাল ট্রিতে বসে এবং একটিটি ডেটাবাইন্ডিং করে Windowএবং ডায়ালগটি দেখায় এবং লুকিয়ে রাখে। আপনি এটি এখানে খুঁজে পেতে পারেন: http://www.codeproject.com/KB/WPF/XAMLDialog.aspx

এটি সত্যই সহজভাবে ব্যবহার করা যায় এবং আপনার ভিউমোডেলে কোনও অদ্ভুত পরিবর্তন প্রয়োজন হয় না এবং ইভেন্ট বা বার্তা প্রয়োজন হয় না। প্রাথমিক কলটি এরকম দেখাচ্ছে:

<dialog:Dialog Content="{Binding Path=DialogViewModel}" Showing="True" />

আপনি সম্ভবত একটি স্টাইল যুক্ত করতে চান Showing। আমি আমার নিবন্ধে এটি ব্যাখ্যা। আমি আশা করি এটা আপনাকে সাহায্য করবে।


2
এটি এমভিভিএম-এ ডায়লগ উইন্ডোগুলি দেখানোর সমস্যাটির জন্য একটি সত্যই আকর্ষণীয় পন্থা।
dthrasher

2
"Showing a dialog requires a code-behind"মিমিএম আপনি ভিউমোডেলে
হেনসলে

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

25

আমি এই পদ্ধতিটি এমভিভিএমের সাথে সংলাপগুলির জন্য ব্যবহার করি ।

আমাকে এখন যা করতে হবে তা হ'ল আমার ভিউ মডেল থেকে নিম্নলিখিতটি কল করা।

var result = this.uiDialogService.ShowDialog("Dialogwindow title goes here", dialogwindowVM);

uiDialogService কোন লাইব্রেরি থেকে আসে?
aggietech

1
কোন গ্রন্থাগার নেই। এটি কেবল একটি ছোট ইন্টারফেস এবং বাস্তবায়ন: স্ট্যাকওভারফ্লো . com / জিজ্ঞাসা / 80৮০১11১/২ । এটি ন্যায্য এটিএম হওয়ার জন্য এটি আমার প্রয়োজনের জন্য আরও কিছু ওভারলোড রয়েছে :) (উচ্চতা, প্রস্থ, প্রপার্টি
সেটিংস

16

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

এখানে পূর্ণ সিলভারলাইট 4 সমাধান দেখুন এমভিভিএম এবং সিলভারলাইট 4 এর সাথে মডেল সংলাপগুলি


@ এলাদ কাটজের মতামত যেমন আপনার উত্তরটিতে লিঙ্কযুক্ত বিষয়বস্তুর অভাব রয়েছে - দয়া করে আপনার উত্তরটি সন্নিবেশ করে উন্নত করুন কারণ এটি এখানে এসওতে একটি ভাল উত্তর হিসাবে বিবেচিত। তবুও, আপনার অবদানের জন্য ধন্যবাদ! :)
Yoda

6

এমভিভিএম শিখার সময় (এখনও শিখছি) যখন আমি এই ধারণার সাথে সত্যই লড়াই করেছি। আমি কী সিদ্ধান্ত নিয়েছি এবং আমি কী মনে করি অন্যরা ইতিমধ্যে সিদ্ধান্ত নিয়েছে তবে যা আমার কাছে পরিষ্কার ছিল না তা হ'ল:

আমার আসল ধারণাটি ছিল যে কোনও ভিউমোডেলকে ডায়ালগ বাক্সে সরাসরি কল করার অনুমতি দেওয়া উচিত নয় কারণ এতে কোনও ডায়ালগ উপস্থিত হওয়া উচিত তা সিদ্ধান্ত নেওয়ার কোনও ব্যবসা নেই। এর কারণ হিসাবে আমি এমভিপিতে (যেমন দেখুন.সোভসফাইফিল্ড ডায়ালগ () দেখুন) আমি কীভাবে বার্তাগুলি পাস করতে পারি তা ভাবতে শুরু করি। তবে আমি মনে করি এটিই ভুল পদ্ধতির is

কোনও ভিউমোডেলের পক্ষে সরাসরি একটি ডায়ালগ কল করা ঠিক। যাইহোক, আপনি যখন ভিউমোডেলটি পরীক্ষা করছেন, তার অর্থ হ'ল ডায়ালগটি হয় আপনার পরীক্ষার সময় পপ আপ হয়ে যায় বা সমস্ত একসাথে ব্যর্থ হয় (সত্যিই এটি কখনও চেষ্টা করা হয়নি)।

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

আপনার ইতিমধ্যে কিছু প্রকারের পরিষেবা লোকেটার বা আইওসি ব্যবহার করা উচিত যা আপনি প্রসঙ্গের উপর নির্ভর করে আপনাকে সঠিক সংস্করণ সরবরাহ করতে কনফিগার করতে পারেন।

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

আশাকরি এটা সাহায্য করবে.


6

এটি করার দুটি ভাল উপায় রয়েছে, 1) একটি কথোপকথন পরিষেবা (সহজ, পরিষ্কার) এবং 2) সহায়তা সহ দেখুন। সহায়তা সহ দেখুন কিছু ঝরঝরে বৈশিষ্ট্য সরবরাহ করে তবে এটি সাধারণত মূল্য দেয় না।

ডায়ালগ সার্ভিস

ক) কনস্ট্রাক্টর বা কোনও নির্ভরশীল ধারক হিসাবে একটি ডায়ালগ পরিষেবা ইন্টারফেস:

interface IDialogService { Task ShowDialogAsync(DialogViewModel dlgVm); }

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

খ) ব্যবহার করার জন্য, কেবলমাত্র ডায়লগভিউমোডেল-উত্পন্ন ক্লাসের জন্য আপনার ডায়ালগস সার্ভিস.শোডায়ালগ (মাইডিএলজিভিএম) কল করুন। প্রত্যাবর্তনের প্রত্যাশার পরে, কী ঘটেছে তা নির্ধারণ করার জন্য আপনার ডায়ালগ ভিএম-এ যুক্ত হওয়া বৈশিষ্ট্যগুলি দেখুন; এমনকি আপনার কলব্যাকেরও দরকার নেই।

সহায়তা দেখুন

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

ক) একটি কাস্টম পেওলড (একটি ডায়ালগভিউমোডেল উত্পন্ন ক্লাস) সহ একটি ওপেনএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্স ডায়ালগএভেন্ট তৈরি করুন।

খ) ভিউটির অনডেটাঙ্কটেক্সট চেঞ্জড ইভেন্টটিতে ইভেন্টটি সাবস্ক্রাইব করুন। পুরানো মান! = নাল এবং উইন্ডোর আনলোড হওয়া ইভেন্টে লুকিয়ে রাখার এবং সাবস্ক্রাইব করতে ভুলবেন না।

গ) ইভেন্টটি আগুনের সময়, ভিউটি আপনার দৃষ্টিভঙ্গিটি খুলুন, যা আপনার পৃষ্ঠার কোনও উত্সে থাকতে পারে বা আপনি এটি অন্য কোথাও কনভেনশন দ্বারা সনাক্ত করতে পারেন (ডায়ালগ পরিষেবা পদ্ধতির মতো)।

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

এটি কথোপকথনগুলিকে প্রকৃতপক্ষে ব্যবহৃত স্থানটির কাছাকাছি থাকতে দেয়, কেবলমাত্র বর্তমান ক্রিয়াকলাপ সম্পর্কিত অ্যাপ্লিকেশনটির কিছু অংশ কমিয়ে দেয় এবং ব্যবহারকারীকে ম্যানুয়ালি ডায়ালগগুলি দূরে সরিয়ে না দিয়ে এমনকি অ্যাপ্লিকেশনের মধ্যে ঘুরতে দেয়, এমনকি একাধিক অর্ধ- মডেল ডায়ালগগুলি বিভিন্ন ট্যাব বা উপ-দর্শনগুলিতে খোলে।


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

4

একটি জমাট কমান্ড ব্যবহার করুন

<Grid>
        <Grid.DataContext>
            <WpfApplication1:ViewModel />
        </Grid.DataContext>


        <Button Content="Text">
            <Button.Command>
                <WpfApplication1:MessageBoxCommand YesCommand="{Binding MyViewModelCommand}" />
            </Button.Command>
        </Button>

</Grid>
public class MessageBoxCommand : Freezable, ICommand
{
    public static readonly DependencyProperty YesCommandProperty = DependencyProperty.Register(
        "YesCommand",
        typeof (ICommand),
        typeof (MessageBoxCommand),
        new FrameworkPropertyMetadata(null)
        );


    public static readonly DependencyProperty OKCommandProperty = DependencyProperty.Register(
        "OKCommand",
        typeof (ICommand),
        typeof (MessageBoxCommand),
        new FrameworkPropertyMetadata(null)
        );


    public static readonly DependencyProperty CancelCommandProperty = DependencyProperty.Register(
        "CancelCommand",
        typeof (ICommand),
        typeof (MessageBoxCommand),
        new FrameworkPropertyMetadata(null)
        );


    public static readonly DependencyProperty NoCommandProperty = DependencyProperty.Register(
        "NoCommand",
        typeof (ICommand),
        typeof (MessageBoxCommand),
        new FrameworkPropertyMetadata(null)
        );


    public static readonly DependencyProperty MessageProperty = DependencyProperty.Register(
        "Message",
        typeof (string),
        typeof (MessageBoxCommand),
        new FrameworkPropertyMetadata("")
        );

    public static readonly DependencyProperty MessageBoxButtonsProperty = DependencyProperty.Register(
        "MessageBoxButtons",
        typeof(MessageBoxButton),
        typeof(MessageBoxCommand),
        new FrameworkPropertyMetadata(MessageBoxButton.OKCancel)
        );

    public ICommand YesCommand
    {
        get { return (ICommand) GetValue(YesCommandProperty); }
        set { SetValue(YesCommandProperty, value); }
    }

    public ICommand OKCommand
    {
        get { return (ICommand) GetValue(OKCommandProperty); }
        set { SetValue(OKCommandProperty, value); }
    }

    public ICommand CancelCommand
    {
        get { return (ICommand) GetValue(CancelCommandProperty); }
        set { SetValue(CancelCommandProperty, value); }
    }

    public ICommand NoCommand
    {
        get { return (ICommand) GetValue(NoCommandProperty); }
        set { SetValue(NoCommandProperty, value); }
    }

    public MessageBoxButton MessageBoxButtons
    {
        get { return (MessageBoxButton)GetValue(MessageBoxButtonsProperty); }
        set { SetValue(MessageBoxButtonsProperty, value); }
    }

    public string Message
    {
        get { return (string) GetValue(MessageProperty); }
        set { SetValue(MessageProperty, value); }
    }

    public void Execute(object parameter)
    {
        var messageBoxResult = MessageBox.Show(Message);
        switch (messageBoxResult)
        {
            case MessageBoxResult.OK:
                OKCommand.Execute(null);
                break;
            case MessageBoxResult.Yes:
                YesCommand.Execute(null);
                break;
            case MessageBoxResult.No:
                NoCommand.Execute(null);
                break;
            case MessageBoxResult.Cancel:
                if (CancelCommand != null) CancelCommand.Execute(null); //Cancel usually means do nothing ,so can be null
                break;

        }
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;


    protected override Freezable CreateInstanceCore()
    {
        throw new NotImplementedException();
    }
}

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

3

আমি মনে করি যে একটি কথোপকথন পরিচালনা করা দর্শনটির দায়িত্ব হওয়া উচিত এবং এটিকে সমর্থন করার জন্য দৃশ্যের কোড থাকা দরকার।

আপনি যদি ভিউমোডেল পরিবর্তন করেন - সংলাপগুলি পরিচালনা করতে মিথস্ক্রিয়াটি দেখুন তবে ভিউমোডেল সেই বাস্তবায়নের উপর নির্ভরশীল। এই সমস্যাটি মোকাবেলার সহজ উপায় হ'ল কার্য সম্পাদন করার জন্য ভিউকে দায়বদ্ধ করে তোলা। এর অর্থ যদি কোনও ডায়ালগ দেখানো হয় তবে জরিমানা, তবে এটি স্ট্যাটাস বারে কোনও স্থিতি বার্তা ইত্যাদিও হতে পারে etc.

আমার বক্তব্যটি এমভিভিএম প্যাটার্নের পুরো পয়েন্টটি হ'ল জিইউআই থেকে ব্যবসায়িক লজিককে পৃথক করা, সুতরাং আপনার ব্যবসায়ের স্তরটিতে (ভিউমোডেল) জিইউআই যুক্তি (একটি কথোপকথন প্রদর্শনের জন্য) মিশ্রণ করা উচিত নয়।


2
ভিএম কখনও ডায়ালগটি হ্যান্ডেল করতে পারে না, আমার উদাহরণস্বরূপ এটিতে এমন কোনও ইভেন্ট হবে যাতে ডায়ালগটি জ্বালিয়ে ফেলা এবং ইভেন্টআর্গের কোনও আকারে তথ্য ফেরত দেওয়া দরকার। ভিউ যদি দায়ী হয় তবে কীভাবে এটি ভিএম-এর কাছে তথ্য ফেরত দেয়?
রায় বুয়সেন

বলুন ভিএমকে কিছু মুছতে হবে। ভিএম ভিউ মুছতে একটি পদ্ধতি কল করে যা একটি বুলিয়ান দেয়। এরপরে দৃশ্যটি হয় হয় সরাসরি আইটেমটি মুছতে এবং সত্যে ফিরে আসতে পারে, বা একটি নিশ্চিতকরণ ডায়ালগ প্রদর্শন করতে পারে এবং ব্যবহারকারীর উত্তরের উপর নির্ভর করে সত্য / মিথ্যা প্রত্যাবর্তন করতে পারে।
ক্যামেরন ম্যাকফারল্যান্ড

ভিএম ডায়ালগ সম্পর্কে কিছুই জানে না তবে কেবলমাত্র ভিউটিকে এমন কিছু মুছতে বলেছে, যা দৃশ্যটি নিশ্চিত বা অস্বীকার করেছে।
ক্যামেরন ম্যাকফারল্যান্ড

আমি সর্বদা ভাবতাম যে এমভিভিএমের পয়েন্টটি ছিল মডেল: ব্যবসায়িক যুক্তি, ভিউমোডেল: জিইউআই যুক্তি এবং দেখুন: কোনও যুক্তি নেই। যা আপনার শেষ অনুচ্ছেদে কোনওভাবে বিপরীত। দয়া করে ব্যাখ্যা করুন!
ডেভিড স্মিট

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

3

একটি আকর্ষণীয় বিকল্প হল নিয়ন্ত্রণগুলি ব্যবহার করা যা দর্শনগুলি (কথোপকথনগুলি) দেখানোর জন্য দায়বদ্ধ।

এটি কীভাবে কাজ করে তা ডাব্লুপিএফ অ্যাপ্লিকেশন ফ্রেমওয়ার্ক (ডাব্লুএএফ) দেখায় ।


3

কেন কেবল ভিএম-তে একটি ইভেন্ট উত্থাপন করবেন না এবং দেখুন ইভেন্টটিতে সাবস্ক্রাইব করবেন? এটি অ্যাপ্লিকেশনটির যুক্তি এবং দর্শনকে পৃথক করে রাখবে এবং এখনও আপনাকে ডায়ালগগুলির জন্য একটি শিশু উইন্ডো ব্যবহার করার অনুমতি দেবে।


3

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

কীভাবে ডাব্লুপিএফকে এমন আচরণ করা যায় যেন এমভিভিএম বক্সের বাইরে সমর্থিত হয়


1
আপনার উত্তরের জন্য এখানে পুরো কোডটি অন্তর্ভুক্ত করা উচিত যা ভাল উত্তরগুলির জন্য এসও প্রয়োজন। তবুও, লিঙ্কযুক্ত পদ্ধতিটি বেশ ঝরঝরে, সুতরাং এর জন্য ধন্যবাদ! :)
Yoda

2
@ ইয়োদা পুরো কোডটি বেশ লম্বা, এবং সে কারণেই আমি এর সাথে লিঙ্ক করব। পরিবর্তনগুলি
প্রতিবিম্বিত

উন্নতির জন্য ধন্যবাদ। যাইহোক, কোনও দিন অফলাইন হতে পারে এমন লিঙ্কের চেয়ে এসওতে দীর্ঘ 3 কোড পূর্ণ পৃষ্ঠা স্ক্রোল সরবরাহ করা ভাল। জটিল বিষয়গুলির জন্য ভাল নিবন্ধগুলি সর্বদা দীর্ঘ দীর্ঘ - এবং আমি কোনও নতুন ট্যাব খোলার, এতে স্যুইচ করে এবং তার আগে যে পৃষ্ঠা / ট্যাবটিতে ছিলাম সেখানে স্ক্রোলিংয়ের মাধ্যমে সেখানে স্ক্রোল করে কোনও লাভ দেখছি না। ;)
যোদা

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

2

আমি মনে করি ভিউ মডেল থেকে ইভেন্টটি পরিচালনা করার জন্য ভিউটিতে কোড থাকতে পারে।

ইভেন্ট / দৃশ্যের উপর নির্ভর করে এর মধ্যে একটি ইভেন্ট ট্রিগারও থাকতে পারে যা মডেল ইভেন্টগুলি দেখতে সাবস্ক্রাইব করে, এবং এক বা একাধিক ক্রিয়া প্রতিক্রিয়া জানাতে।


2

আমারও একই অবস্থা ছিল এবং মেসেজবক্সকে একটি ডিজাইনারের অদৃশ্য নিয়ন্ত্রণে মুড়িয়ে ফেলা হয়েছিল। বিশদটি আমার ব্লগে রয়েছে

http://geekswithblogs.net/mukapu/archive/2010/03/12/user-prompts-messagebox-with-mvvm.aspx

একই কোনও মোডাল ডায়লগ, ফাইল ব্রাউজ নিয়ন্ত্রণ ইত্যাদিতে প্রসারিত হতে পারে



1

কার্ল শিফলেট সার্ভিস অ্যাপ্রোচ এবং প্রিজম ইন্টারঅ্যাকশনরেউকোস্ট অ্যাপ্রোচ ব্যবহার করে ডায়লগ বাক্সগুলি দেখানোর জন্য একটি নমুনা অ্যাপ্লিকেশন তৈরি করেছে।

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

http://karlshifflett.wordpress.com/2010/11/07/in-the-box-ndash-mvvm-training/


1

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

https://github.com/Plasma-Paris/Plasma.WpfUtils

আপনি এটি এর মতো ব্যবহার করতে পারেন:

public RelayCommand YesNoMessageBoxCommand { get; private set; }
async void YesNoMessageBox()
{
    var result = await _Service.ShowMessage("This is the content of the message box", "This is the title", System.Windows.MessageBoxButton.YesNo);
    if (result == System.Windows.MessageBoxResult.Yes)
        // [...]
}

অথবা আপনি আরও পরিশীলিত পপিন চাইলে এটি পছন্দ করুন:

var result = await _Service.ShowCustomMessageBox(new MyMessageBoxViewModel { /* What you want */ });

এবং এটি এই জাতীয় জিনিস দেখায়:

2


1

স্ট্যান্ডার্ড পদ্ধতির

ডাব্লুপিএফ-এ এই সমস্যাটি মোকাবেলায় বছর কাটিয়ে যাওয়ার পরে অবশেষে ডাব্লুপিএফ-এ সংলাপগুলি বাস্তবায়নের মানক উপায়টি আবিষ্কার করেছি। এখানে এই পদ্ধতির সুবিধা রয়েছে:

  1. শুচি
  2. এমভিভিএম ডিজাইন প্যাটার্ন লঙ্ঘন করে না
  3. ভিউমোডাল কখনই কোনও ইউআই লাইব্রেরির উল্লেখ করে না (উইন্ডোবেস, উপস্থাপনা ফ্রেমওয়ার্ক ইত্যাদি)
  4. স্বয়ংক্রিয় পরীক্ষার জন্য উপযুক্ত
  5. ডায়ালগগুলি সহজেই প্রতিস্থাপন করা যায়।

তাহলে কী কী। এইটা ডিআই + আইওসি

এটা যেভাবে কাজ করে। আমি এমভিভিএম লাইট ব্যবহার করছি, তবে এই পদ্ধতিটি অন্যান্য ফ্রেমওয়ার্কগুলিতেও প্রসারিত হতে পারে:

  1. আপনার সমাধানে একটি WPF অ্যাপ্লিকেশন প্রকল্প যুক্ত করুন। ডাকা অ্যাপ
  2. একটি ভিউমোডাল ক্লাস লাইব্রেরি যুক্ত করুন। ডাকা ভিএম বলুন
  3. অ্যাপ্লিকেশন রেফারেন্স ভিএম প্রকল্প। ভিএম প্রকল্প অ্যাপ সম্পর্কে কিছুই জানে না।
  4. দুটি প্রকল্পে এমভিভিএম লাইটের নিউগেট রেফারেন্স যুক্ত করুন । আমি আজকাল এমভিভিএম লাইট স্ট্যান্ডার্ডটি ব্যবহার করছি তবে আপনি পুরো ফ্রেমওয়ার্ক সংস্করণেও ঠিক আছেন।
  5. ভিএম প্রোজেক্টে একটি ইন্টারফেস আইডিয়ালোগস সার্ভিস যুক্ত করুন :

    public interface IDialogService
    {
      void ShowMessage(string msg, bool isError);
      bool AskBooleanQuestion(string msg);
      string AskStringQuestion(string msg, string default_value);
    
      string ShowOpen(string filter, string initDir = "", string title = "");
      string ShowSave(string filter, string initDir = "", string title = "", string fileName = "");
      string ShowFolder(string initDir = "");
    
      bool ShowSettings();
    }
  6. IDialogServiceআপনার প্রকারের একটি সর্বজনীন স্থিতিশীল সম্পত্তি প্রকাশ করুন ViewModelLocatorতবে দেখুন স্তরটি সম্পাদনের জন্য নিবন্ধকরণ অংশটি ছেড়ে দিন। এটিই মূল

    public static IDialogService DialogService => SimpleIoc.Default.GetInstance<IDialogService>();
  7. অ্যাপ্লিকেশন প্রকল্পে এই ইন্টারফেসের একটি বাস্তবায়ন যুক্ত করুন।

    public class DialogPresenter : IDialogService
    {
        private static OpenFileDialog dlgOpen = new OpenFileDialog();
        private static SaveFileDialog dlgSave = new SaveFileDialog();
        private static FolderBrowserDialog dlgFolder = new FolderBrowserDialog();
    
        /// <summary>
        /// Displays a simple Information or Error message to the user.
        /// </summary>
        /// <param name="msg">String text that is to be displayed in the MessageBox</param>
        /// <param name="isError">If true, Error icon is displayed. If false, Information icon is displayed.</param>
        public void ShowMessage(string msg, bool isError)
        {
                if(isError)
                        System.Windows.MessageBox.Show(msg, "Your Project Title", MessageBoxButton.OK, MessageBoxImage.Error);
                else
                        System.Windows.MessageBox.Show(msg, "Your Project Title", MessageBoxButton.OK, MessageBoxImage.Information);
        }
    
        /// <summary>
        /// Displays a Yes/No MessageBox.Returns true if user clicks Yes, otherwise false.
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool AskBooleanQuestion(string msg)
        {
                var Result = System.Windows.MessageBox.Show(msg, "Your Project Title", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes;
                return Result;
        }
    
        /// <summary>
        /// Displays Save dialog. User can specify file filter, initial directory and dialog title. Returns full path of the selected file if
        /// user clicks Save button. Returns null if user clicks Cancel button.
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="initDir"></param>
        /// <param name="title"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public string ShowSave(string filter, string initDir = "", string title = "", string fileName = "")
        {
                if (!string.IsNullOrEmpty(title))
                        dlgSave.Title = title;
                else
                        dlgSave.Title = "Save";
    
                if (!string.IsNullOrEmpty(fileName))
                        dlgSave.FileName = fileName;
                else
                        dlgSave.FileName = "";
    
                dlgSave.Filter = filter;
                if (!string.IsNullOrEmpty(initDir))
                        dlgSave.InitialDirectory = initDir;
    
                if (dlgSave.ShowDialog() == DialogResult.OK)
                        return dlgSave.FileName;
                else
                        return null;
        }
    
    
        public string ShowFolder(string initDir = "")
        {
                if (!string.IsNullOrEmpty(initDir))
                        dlgFolder.SelectedPath = initDir;
    
                if (dlgFolder.ShowDialog() == DialogResult.OK)
                        return dlgFolder.SelectedPath;
                else
                        return null;
        }
    
    
        /// <summary>
        /// Displays Open dialog. User can specify file filter, initial directory and dialog title. Returns full path of the selected file if
        /// user clicks Open button. Returns null if user clicks Cancel button.
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="initDir"></param>
        /// <param name="title"></param>
        /// <returns></returns>
        public string ShowOpen(string filter, string initDir = "", string title = "")
        {
                if (!string.IsNullOrEmpty(title))
                        dlgOpen.Title = title;
                else
                        dlgOpen.Title = "Open";
    
                dlgOpen.Multiselect = false;
                dlgOpen.Filter = filter;
                if (!string.IsNullOrEmpty(initDir))
                        dlgOpen.InitialDirectory = initDir;
    
                if (dlgOpen.ShowDialog() == DialogResult.OK)
                        return dlgOpen.FileName;
                else
                        return null;
        }
    
        /// <summary>
        /// Shows Settings dialog.
        /// </summary>
        /// <returns>true if User clicks OK button, otherwise false.</returns>
        public bool ShowSettings()
        {
                var w = new SettingsWindow();
                MakeChild(w); //Show this dialog as child of Microsoft Word window.
                var Result = w.ShowDialog().Value;
                return Result;
        }
    
        /// <summary>
        /// Prompts user for a single value input. First parameter specifies the message to be displayed in the dialog 
        /// and the second string specifies the default value to be displayed in the input box.
        /// </summary>
        /// <param name="m"></param>
        public string AskStringQuestion(string msg, string default_value)
        {
                string Result = null;
    
                InputBox w = new InputBox();
                MakeChild(w);
                if (w.ShowDialog(msg, default_value).Value)
                        Result = w.Value;
    
                return Result;
        }
    
        /// <summary>
        /// Sets Word window as parent of the specified window.
        /// </summary>
        /// <param name="w"></param>
        private static void MakeChild(System.Windows.Window w)
        {
                IntPtr HWND = Process.GetCurrentProcess().MainWindowHandle;
                var helper = new WindowInteropHelper(w) { Owner = HWND };
        }
    }
  8. এই ফাংশন কিছু জেনেরিক হলেও ( ShowMessage, AskBooleanQuestionইত্যাদি), জন এই প্রোজেক্ট এবং ব্যবহার কাস্টম নির্দিষ্ট Windowগুলি। আপনি একই ফ্যাশনে আরও কাস্টম উইন্ডো যুক্ত করতে পারেন। কীটি হ'ল ইউআই-নির্দিষ্ট উপাদানগুলিকে ভিউ লেয়ারে রাখা এবং ভিএম লেয়ারে পোকো ব্যবহার করে ফিরিয়ে নেওয়া ডেটা প্রকাশ করা
  9. এই ক্লাসটি ব্যবহার করে ভিও লেয়ারটিতে আপনার ইন্টারফেসটি আইওসি রেজিস্ট্রেশন করুন। আপনি এটি আপনার মূল দর্শকের কনস্ট্রাক্টরে ( InitializeComponent()কল করার পরে ) করতে পারেন:

    SimpleIoc.Default.Register<IDialogService, DialogPresenter>();
  10. এই নাও. ভিএম এবং ভিউ স্তর উভয় ক্ষেত্রেই আপনার এখন সমস্ত সংলাপ কার্যকারিতা অ্যাক্সেস রয়েছে। আপনার ভিএম স্তর এই ফাংশনগুলিকে কল করতে পারে:

    var NoTrump = ViewModelLocator.DialogService.AskBooleanQuestion("Really stop the trade war???", "");
  11. তাই পরিষ্কার আপনি দেখতে। কীভাবে হ্যাঁ / কোনও প্রশ্ন ইউআই স্তর দ্বারা ব্যবহারকারীর সামনে উপস্থাপন করা হবে এবং ডায়ালগ থেকে প্রাপ্ত ফলাফলের সাথে সফলভাবে কাজ করতে পারে সে সম্পর্কে ভিএম স্তর কিছুই জানে না।

অন্যান্য ফ্রি পার্কস ks

  1. ইউনিট পরীক্ষা লেখার জন্য, আপনি IDialogServiceআপনার পরীক্ষার প্রকল্পের একটি কাস্টম বাস্তবায়ন সরবরাহ করতে পারেন এবং আইওসিতে class শ্রেণীর নির্মাতাকে আপনার পরীক্ষার শ্রেণিতে নিবন্ধন করতে পারেন।
  2. আপনাকে কিছু নাম স্থান যেমন আমদানি করতে হবে যেমন Microsoft.Win32খুলুন এবং সংরক্ষণ করুন ডায়ালগ অ্যাক্সেস করতে। আমি এগুলি এড়িয়ে গিয়েছি কারণ এই ডায়ালগগুলির একটি উইনফর্মস সংস্করণও উপলভ্য রয়েছে, প্লাস কেউ তাদের নিজস্ব সংস্করণ তৈরি করতে চাইবে। এছাড়াও মনে রাখবেন যে ব্যবহৃত কিছু শনাক্তকারী হ'ল DialogPresenterআমার নিজস্ব উইন্ডোর নাম (যেমন SettingsWindow)। আপনাকে সেগুলি উভয়ই ইন্টারফেস এবং বাস্তবায়ন উভয় থেকে অপসারণ করতে হবে বা আপনার নিজের উইন্ডো সরবরাহ করতে হবে।
  3. যদি আপনার ভিএম মাল্টি-থ্রেডিং সম্পাদন করে তবে DispatcherHelper.Initialize()আপনার অ্যাপ্লিকেশনটির জীবন চক্রের শুরুতে এমভিভিএম লাইটকে কল করুন ।
  4. ছাড়া জন্য DialogPresenterযা দেখুন স্তরে ইনজেকশনের হয়, অন্যান্য ViewModals নিবন্ধিত করা উচিত ViewModelLocatorএবং তারপর যে ধরনের একটি পাবলিক স্ট্যাটিক সম্পত্তি দেখতে স্তর গ্রাস জন্য উন্মুক্ত করা উচিত। এটার মতো কিছু:

    public static SettingsVM Settings => SimpleIoc.Default.GetInstance<SettingsVM>();
  5. বেশিরভাগ অংশের জন্য, আপনার ডায়লগগুলিতে কোনও বাঁধাই বা ডেটা কনটেক্সট সেট করার মতো জিনিসগুলির জন্য কোনও কোড-ব্যাকড থাকা উচিত নয় You এমনকি আপনি কনস্ট্রাক্টর পরামিতি হিসাবে জিনিসগুলিও পাস করবেন না। এক্সএএমএল আপনার পক্ষে এটি করতে পারে, এর মতো:

    <Window x:Class="YourViewNamespace.SettingsWindow"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:local="clr-namespace:YourViewProject"
      xmlns:vm="clr-namespace:YourVMProject;assembly=YourVMProject"
      DataContext="{x:Static vm:ViewModelLocator.Settings}"
      d:DataContext="{d:DesignInstance Type=vm:SettingsVM}" />
  6. DataContextএই পদ্ধতিতে সেট করা আপনাকে সমস্ত ধরণের ডিজাইন-সময় সুবিধা দেয় যেমন ইন্টেলিসেন্স এবং স্বতঃপূরণ।

আশা করি সবাইকে সাহায্য করবে


0

কোনও কাজ বা কথোপকথনের ভিউ মডেলটি কেমন হওয়া উচিত তা জিজ্ঞাসা করার সময় আমিও একই ধরণের সমস্যা নিয়ে ভাবছিলাম ।

আমার বর্তমান সমাধানটি এর মতো দেখাচ্ছে:

public class SelectionTaskModel<TChoosable> : ViewModel
    where TChoosable : ViewModel
{
    public SelectionTaskModel(ICollection<TChoosable> choices);
    public ReadOnlyCollection<TChoosable> Choices { get; }
    public void Choose(TChoosable choosen);
    public void Abort();
}

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


0

আমি একই সমস্যা নিয়ে লড়াই করেছি। আমি ভিউ এবং ভিউমোডেলের মধ্যে আন্তঃসংযোগ করার একটি উপায় নিয়ে এসেছি। আপনি মেসেজবক্স দেখাতে বলার জন্য ভিউমোডেল থেকে ভিউতে কোনও বার্তা প্রেরণ শুরু করতে পারেন এবং ফলাফলের সাথে এটি আবার রিপোর্ট করবে। তারপরে ভিউমোডেল ভিউ থেকে ফিরে আসা ফলাফলটির প্রতিক্রিয়া জানাতে পারে।

আমি আমার ব্লগে এটি প্রদর্শন করে :


0

আমি এই বিষয়টি সম্পর্কে মোটামুটি একটি নিবন্ধ লিখেছি এবং এমভিভিএম ডায়ালগগুলির জন্য একটি পপ-ইন গ্রন্থাগারও তৈরি করেছি। এমভিভিএমের কঠোর আনুগত্য কেবল সম্ভব নয় তবে সঠিকভাবে প্রয়োগ করা হলে খুব পরিষ্কার হয় এবং এটি তৃতীয় পক্ষের লাইব্রেরিতে সহজেই প্রসারিত করা যেতে পারে যা এগুলি নিজে মানায় না:

https://www.codeproject.com/Articles/820324/Implementing-Dialog-Boxes-in-MVVM


0

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

এটি তুচ্ছ নয় তবে এটি খুব জটিলও নয়। এবং এটি প্রিজমে অন্তর্নির্মিত এবং তাই আইএমএইচওর অনুশীলন সেরা best

আমার 2 সেন্ট!


-1

সম্পাদনা: হ্যাঁ আমি সম্মতি জানাই এটি সঠিক এমভিভিএম পদ্ধতি নয় এবং আমি এখন ব্লাইন্ডমিসের পরামর্শ অনুসারে অনুরূপ কিছু ব্যবহার করছি।

আপনি যেভাবে যেতে পারেন তার একটি উপায়

আপনার মেইন ভিউ মডেলে (যেখানে আপনি মডেলটি খুলবেন):

void OpenModal()
{
    ModalWindowViewModel mwvm = new ModalWindowViewModel();
    Window mw = new Window();
    mw.content = mwvm;
    mw.ShowDialog()
    if(mw.DialogResult == true)
    { 
        // Your Code, you can access property in mwvm if you need.
    }
}

এবং আপনার মডেল উইন্ডোতে ভিউ / ভিউমডেল:

XAML:

<Button Name="okButton" Command="{Binding OkCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">OK</Button>
<Button Margin="2" VerticalAlignment="Center" Name="cancelButton" IsCancel="True">Cancel</Button>

ViewModel:

public ICommand OkCommand
{
    get
    {
        if (_okCommand == null)
        {
            _okCommand = new ActionCommand<Window>(DoOk, CanDoOk);
        }
        return _okCommand ;
    }
}

void DoOk(Window win)
{
    <!--Your Code-->
    win.DialogResult = true;
    win.Close();
}

bool CanDoOk(Window win) { return true; }

বা এখানে যা পোস্ট করা হয়েছে তার অনুরূপ ডাব্লুপিএফ এমভিভিএম: উইন্ডোটি কীভাবে বন্ধ করতে হয়


2
আমি ডাউনভোট ছিলাম না, তবে আমার সন্দেহ হয় কারণ ভিউ-মডেলের ভিউয়ের প্রত্যক্ষ রেফারেন্স রয়েছে।
ব্রায়ান গিডন

@ ব্রায়ানজিডন, আপনার মন্তব্যের জন্য ধন্যবাদ আমি সম্মত এটি একটি decoupled সমাধান নয়। আসলে, আমি ব্লাইন্ডমেস দ্বারা প্রস্তাবিত ওহারের অনুরূপ কিছু ব্যবহার করছি না। আবার ধন্যবাদ.
সাইমন

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