রিলেটিভসোর্সের সাথে আমি কীভাবে ডাব্লুপিএফ বাইন্ডিং ব্যবহার করব?


উত্তর:


782

আপনি যদি বস্তুর অন্য কোনও সম্পত্তিতে আবদ্ধ হতে চান:

{Binding Path=PathToProperty, RelativeSource={RelativeSource Self}}

আপনি যদি কোনও পূর্বপুরুষের কাছে সম্পত্তি পেতে চান:

{Binding Path=PathToProperty,
    RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}

আপনি যদি মুগ্ধ পিতামাতার উপর কোনও সম্পত্তি পেতে চান (যাতে আপনি একটি কন্ট্রোল টেম্পলেটটিতে 2 উপায় বাইন্ডিং করতে পারেন)

{Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}

বা, সংক্ষিপ্ত (এটি কেবল ওয়ানওয়ে বাইন্ডিংয়ের জন্য কাজ করে):

{TemplateBinding Path=PathToProperty}

15
এটির জন্য "{বাইন্ডিং পাথ = পাথোপ্রোপার্টি, রিলেটিভসোর্স = {রিলেটিভসোর্স পূর্বসূরি টাইপ = {এক্স: টাইপঅফঅ্যান্টিস্টর}}}" টাইপ করা আছে, দেখে মনে হচ্ছে এটি "মোড = ফাইন্ডএন্টিস্টর" থাকা দরকার, "পূর্বসূরি টাইপ" এর আগে
এডওয়ার্ডএম

1
কোন প্রযুক্তির জন্য? ডাব্লুপিএফ-তে, যখন আপনি কোনও নির্দিষ্ট করে থাকেন তখন তা অনুমান করা হয় AncestorType
আবে হেডব্র্যাচট

2
আমি @ অ্যাডওয়ার্ডএম এর সাথে একমত আমি বাদ দিলে FindAncestor, এর আগে AncestorType, আমি নিম্নলিখিত ত্রুটিটি পাই: "রিলেটিভসোর্স ফাইন্ডএন্টস্টোর মোডে নেই"। (ভিএস ২০১৩-তে, সম্প্রদায় সংস্করণে)
কিলোমোট

1
@ কেমোট, এটি নেট নেট 3.0.০ এর পরে থেকে আমার পক্ষে কাজ করেছে এবং আমি আবারও যাচাই করেছিলাম যে এটি কক্সমলে এইভাবে কাজ করে ... আবার আপনি কোন প্রযুক্তি ব্যবহার করছেন? এক্সএএমএল প্রসেসর ডাব্লুপিএফ / সিলভারলাইট / ইউডাব্লুপি-র জন্য আলাদা, তাই আপনার বিভিন্ন প্রযুক্তিতে বিভিন্ন ফলাফল থাকতে পারে। আপনি ভিএস সম্প্রদায়টিও উল্লেখ করেছেন, তাই এটি আইডিই সতর্কতা, তবে রানটাইম এ কাজ করে?
আবে হাইড্রেব্রাক্ট

6
শুধু এখানে খেয়াল করা জরুরী যে আপনি RelativeSource এর DataContext একটি সম্পত্তি বাঁধাই করার চান তারপর আপনি স্পষ্টভাবে এটি নির্দিষ্ট করতে হবে চেয়েছিলেন: {Binding Path=DataContext.SomeProperty, RelativeSource=...। আমি যখন একটি ডেটা টেম্প্লেটের মধ্যে পিতামাতার ডেটা কন্টেক্সটে বাঁধার চেষ্টা করছিলাম তখন এই নবজাতক হিসাবে আমার কাছে কিছুটা অপ্রত্যাশিত ছিল।
ডাঃ এস্পেরেন্টো

133
Binding RelativeSource={
    RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemType}
}
...

এর ডিফল্ট বৈশিষ্ট্য RelativeSourceহ'ল Modeসম্পত্তি। বৈধ মানগুলির একটি সম্পূর্ণ সেট এখানে দেওয়া হয়েছে ( এমএসডিএন থেকে ):

  • পূর্ববর্তী ডেটা প্রদর্শিত তথ্য আইটেমের তালিকায় আপনাকে পূর্ববর্তী ডেটা আইটেম (ডেটা আইটেম ধারণ করে এমন নিয়ন্ত্রণ নয়) বাঁধতে অনুমতি দেয়।

  • TemplatedParent উপাদান যা ফর্মা (যেখানে ডেটা-বাউন্ড উপাদান থাকে) প্রয়োগ করা হয় বোঝায়। এটি একটি টেম্পলেটবাইন্ডিং এক্সটেনশন সেট করার অনুরূপ এবং কেবল তখনই প্রযোজ্য যদি বাঁধাই কোনও টেমপ্লেটের মধ্যে থাকে।

  • স্বয়ং উপাদান যা আপনি বাঁধাই সেটিং এবং আপনি একই উপাদান আরেকটি সম্পত্তিতে যে উপাদান এক সম্পত্তি সহিত আবদ্ধ করতে পারবেন হয় বোঝায়।

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


128

এখানে এমভিভিএম আর্কিটেকচারের প্রসঙ্গে আরও চাক্ষুষ ব্যাখ্যা:

এখানে চিত্র বর্ণনা লিখুন


19
আমি কি কিছু রেখে গেলাম? আপনি কিভাবে এটি একটি সহজ এবং পরিষ্কার গ্রাফিক বিবেচনা করতে পারেন? 1: বামের অর্থের বাক্সগুলি ডানদিকের সাথে সম্পর্কিত নয় (ভিউমোডেলের অভ্যন্তরে একটি .cs ফাইল রয়েছে কেন?) 2: এই ডেটা কনটেক্সট তীরগুলি কী নির্দেশ করে? 3: কেন বার্তা সম্পত্তি ভিউমডেল 1 এ নেই? এবং সর্বাপেক্ষা গুরুত্বপূর্ণ 5: যদি টেক্সটব্লকের ইতিমধ্যে একই ডেটা কনটেক্সট থাকে তবে উইন্ডোটির ডেটা কনটেক্সটে যাওয়ার জন্য আপনার আপেক্ষিক উত্স বাঁধাইয়ের কী দরকার? আমি এখানে স্পষ্টভাবে কিছু অনুপস্থিত করছি তাই হয় আমি বেশ বোবা বা এই গ্রাফিকটি যতটা সহজ মনে হয় তত সহজ এবং স্পষ্ট নয়! দয়া করে আমাকে আলোকিত করুন
মার্কাস হ্যাটার

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

6
@ ম্যাথেজ কারগিলি আমি খুব ভালো করে জানি যে এর অর্থ অনুমিত হওয়ার কথা , এটি আমার বক্তব্য ছিল না। তবে নিজেকে এমন ব্যক্তির অবস্থানে রাখুন যিনি এক্সএএমএল এবং এমভিভিএম ভাল জানেন না এবং আপনি দেখতে পাবেন যে এটি নেই সহজ এবং পরিষ্কার নয়
মার্কাস হ্যাটার

1
আমাকে @ মার্কুস হিটটারের সাথে একমত হতে হবে, যাইহোক, বামদিকে বাঁধাই এই হিসাবে সহজ হতে পারে: {Binding Message}(কিছুটা আরও সাধারণ ...)
ফ্লোরিয়ান

@ ফ্লোরিয়েন আমি অন্তত আমার ব্যবহারের ক্ষেত্রে এমনটি মনে করি না। আমার কাছে একটি ডেটা টেম্পলেট রয়েছে যা ড্রপডাউন মেনুতে (কোনও ডাটাবেস থেকে লোড হওয়া) বিকল্পগুলির তালিকা পেতে মেইন উইন্ডোর ডেটা কনটেক্সট (আমার ভিউমডেল ক্লাস) পড়তে হবে। ডাটাটেম্পলেটটি এমন একটি মডেল অবজেক্টের সাথে আবদ্ধ যে এটি ডেটাবেস থেকে লোড করা হলেও এটি কেবলমাত্র নির্বাচিত বিকল্পটিতে অ্যাক্সেস পায়। Path=DataContext.Messageকাজের বাধ্যবাধকতা পেতে আমাকে স্পষ্টতই সেট করতে হয়েছিল। আপনি প্রস্থ / উচ্চতা / ইত্যাদির সাথে আপেক্ষিক বাঁধাই করতে পারেন তা বোঝা যায়। একটি নিয়ন্ত্রণ।
ডাঃস্পেন্তো

47

বেচির বেজাউই তার নিবন্ধে ডাব্লুপিএফ-তে রিলেটিভসোর্সের ব্যবহারের ঘটনাগুলি এখানে প্রকাশ করেছেন :

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

  1. মোড স্ব:

এই ক্ষেত্রেটি কল্পনা করুন, একটি আয়তক্ষেত্র যা আমরা চাই যে এর উচ্চতা সর্বদা এর প্রস্থের সমান, একটি বর্গ বলা যাক। আমরা উপাদানটির নামটি ব্যবহার করে এটি করতে পারি

<Rectangle Fill="Red" Name="rectangle" 
                Height="100" Stroke="Black" 
                Canvas.Top="100" Canvas.Left="100"
                Width="{Binding ElementName=rectangle,
                Path=Height}"/>

তবে উপরের এই ক্ষেত্রে আমরা বাঁধাই করা অবজেক্টের নাম, আয়তক্ষেত্রটি নির্দেশ করতে বাধ্য। রিলেটিভসোর্সটি ব্যবহার করে আমরা একই উদ্দেশ্যে ভিন্নভাবে পৌঁছাতে পারি

<Rectangle Fill="Red" Height="100" 
               Stroke="Black" 
               Width="{Binding RelativeSource={RelativeSource Self},
               Path=Height}"/>

সেই ক্ষেত্রে আমরা বাধ্যতামূলক বস্তুর নাম উল্লেখ করতে বাধ্য নই এবং যখনই উচ্চতা পরিবর্তন করা হয় তখন প্রস্থ সর্বদা উচ্চতার সমান হবে।

আপনি যদি প্রস্থটিকে উচ্চতার অর্ধেক হতে চান তবে আপনি বাইন্ডিং মার্কআপ এক্সটেনশনে রূপান্তরকারী যুক্ত করে এটি করতে পারেন। আসুন এখন অন্য কেসটি কল্পনা করুন:

 <TextBlock Width="{Binding RelativeSource={RelativeSource Self},
               Path=Parent.ActualWidth}"/>

উপরের কেসটি প্রদত্ত উপাদানের প্রদত্ত সম্পত্তিটিকে তার প্রত্যক্ষ পিতামাতার মধ্যে একটিতে বাঁধতে ব্যবহার করা হয় কারণ এই উপাদানটি প্যারেন্ট নামে পরিচিত একটি সম্পত্তি রাখে। এটি আমাদেরকে অন্য একটি আপেক্ষিক উত্স মোডে নিয়ে যায় যা ফাইন্ডএন্টস্টোরটি।

  1. মোড ফাইন্ডএন্স্টোর

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

<Canvas Name="Parent0">
    <Border Name="Parent1"
             Width="{Binding RelativeSource={RelativeSource Self},
             Path=Parent.ActualWidth}"
             Height="{Binding RelativeSource={RelativeSource Self},
             Path=Parent.ActualHeight}">
        <Canvas Name="Parent2">
            <Border Name="Parent3"
            Width="{Binding RelativeSource={RelativeSource Self},
           Path=Parent.ActualWidth}"
           Height="{Binding RelativeSource={RelativeSource Self},
              Path=Parent.ActualHeight}">
               <Canvas Name="Parent4">
               <TextBlock FontSize="16" 
               Margin="5" Text="Display the name of the ancestor"/>
               <TextBlock FontSize="16" 
                 Margin="50" 
            Text="{Binding RelativeSource={RelativeSource  
                       FindAncestor,
                       AncestorType={x:Type Border}, 
                       AncestorLevel=2},Path=Name}" 
                       Width="200"/>
                </Canvas>
            </Border>
        </Canvas>
     </Border>
   </Canvas>

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

সুতরাং অ্যানস্টোরলিভেল = 2 কে অ্যানস্টোরলিভেল = 1 এ পরিবর্তন করার চেষ্টা করুন এবং দেখুন কী ঘটে। তারপরে পূর্বপুরুষের ধরণটি পূর্বপুরুষের টাইপ = সীমান্ত থেকে পূর্বপুরুষ টাইপ = ক্যানভাসে পরিবর্তন করার চেষ্টা করুন এবং দেখুন কী ঘটেছে।

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

  1. TemplatedParent

এই মোডটি কন্ট্রোলটেম্পলেট প্রয়োগ করা হয় এমন নিয়ন্ত্রণের একটি সম্পত্তিতে প্রদত্ত কন্ট্রোলটিম্পলেট বৈশিষ্ট্যটিকে সক্ষম করে। এখানে সমস্যাটি ভালভাবে বোঝার জন্য উদাহরণ স্বরূপ

<Window.Resources>
<ControlTemplate x:Key="template">
        <Canvas>
            <Canvas.RenderTransform>
                <RotateTransform Angle="20"/>
                </Canvas.RenderTransform>
            <Ellipse Height="100" Width="150" 
                 Fill="{Binding 
            RelativeSource={RelativeSource TemplatedParent},
            Path=Background}">

              </Ellipse>
            <ContentPresenter Margin="35" 
                  Content="{Binding RelativeSource={RelativeSource  
                  TemplatedParent},Path=Content}"/>
        </Canvas>
    </ControlTemplate>
</Window.Resources>
    <Canvas Name="Parent0">
    <Button   Margin="50" 
              Template="{StaticResource template}" Height="0" 
              Canvas.Left="0" Canvas.Top="0" Width="0">
        <TextBlock FontSize="22">Click me</TextBlock>
    </Button>
 </Canvas>

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


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

33

ডাব্লুপিএফ RelativeSourceবাইন্ডিংয়ে তিনটি propertiesসেট করে দেয়:

1. মোড: এটি এমন যেটিরenum চারটি মান থাকতে পারে:

ক। পূর্ববর্তী ডেটা ( value=0): এটি আবদ্ধের পূর্বের মানটি নির্ধারিতpropertyকরে

খ। টেম্পলেটেড প্যারেন্ট ( value=1): যেtemplatesকোনও নিয়ন্ত্রণেরসংজ্ঞা দেওয়ারসময় এবং এর মান / সম্পত্তির সাথে আবদ্ধ হতে চাইলেএটি ব্যবহৃতহয়control

উদাহরণস্বরূপ, সংজ্ঞা দিন ControlTemplate:

  <ControlTemplate>
        <CheckBox IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
 </ControlTemplate>

গ। স্ব ( value=2): যখন আমরাস্বselfবা একটিথেকে বাঁধাই করতে চাইproperty

উদাহরণস্বরূপ: পাঠান চেক করা রাষ্ট্র checkboxহিসাবে CommandParameterযখন সেটিং CommandউপরCheckBox

<CheckBox ...... CommandParameter="{Binding RelativeSource={RelativeSource Self},Path=IsChecked}" />

ঘ। FindAncestor ( value=3): যখন একটি পিতা বা মাতা থেকে জুড়তে অনুমতি চানcontrol মধ্যেVisual Tree

উদাহরণস্বরূপ: বাঁধুন একটি checkboxমধ্যে recordsএকটি যদি grid, যদি header checkboxপরীক্ষা করা হয়

<CheckBox IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}, Path=DataContext.IsHeaderChecked, Mode=TwoWay}" />

২. পূর্বপুরুষFindAncestor টাইপ : যখন মোডটি হয় তখন কোন ধরণের পূর্বপুরুষের সংজ্ঞা দেওয়া হয়

RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}

পূর্বপরিবারের লিভেল: যখন মোড হয়FindAncestorতখন পূর্বপুরুষের স্তরটি (যদি সেখানে দুটি একই ধরণের পিতামাতার থাকেvisual tree)

RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid, AncestorLevel=1}}

উপরে সমস্ত ব্যবহারের ক্ষেত্রে রয়েছে RelativeSource binding

এখানে একটি রেফারেন্স লিঙ্ক


2
দুর্দান্ত ... এটি আমার জন্য কাজ করেছে: <ডেটাগ্রিডচেকবক্সকালাম শিরোলেখ = "প্রদত্ত" প্রস্থ = "35" বাইন্ডিং = "{আপেক্ষিক উত্স মোড = ফাইন্ডএন্টিস্টর, পূর্বপরিচয় টাইপ = {x: টাইপ উইন্ডো} Path, পথ = ডেটা কনটেক্সট.সাইলেক্টডবায়ার। , মোড = ওয়ানওয়ে / "/> যেখানে আমি প্যারেন্ট উইন্ডোটির নির্বাচিত বাইয়ারের সাথে বাঁধতে চেষ্টা করছিলাম sসপেইড সম্পত্তি
মাইকেল কে

21

টেম্পলেটড পিতামাতাকে ভুলে যাবেন না:

<Binding RelativeSource="{RelativeSource TemplatedParent}"/>

অথবা

{Binding RelativeSource={RelativeSource TemplatedParent}}

16

সিলভারলাইটের এই চিন্তাভাবনা জুড়ে যারা হোঁচট খাচ্ছেন তাদের পক্ষে এটি লক্ষণীয়:

সিলভারলাইট এই কমান্ডগুলির মধ্যে কেবল একটি হ্রাসিত উপসেট সরবরাহ করে


হ্যাঁ, আমি এসএল সমর্থনও খুঁজছিলাম। : এটা ভোট দিন connect.microsoft.com/VisualStudio/feedback/details/480603/...
TravisWhidden

16

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

{Binding Path=PathToProperty, RelativeSource={RelativeSource Self}}
{Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}
{Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}
{Binding Path=Text, ElementName=MyTextBox}

পরে:

{BindTo PathToProperty}
{BindTo Ancestor.typeOfAncestor.PathToProperty}
{BindTo Template.PathToProperty}
{BindTo #MyTextBox.Text}

পদ্ধতি বন্ডিং কীভাবে সরল করা যায় তার একটি উদাহরণ এখানে। আগে:

// C# code
private ICommand _saveCommand;
public ICommand SaveCommand {
 get {
  if (_saveCommand == null) {
   _saveCommand = new RelayCommand(x => this.SaveObject());
  }
  return _saveCommand;
 }
}

private void SaveObject() {
 // do something
}

// XAML
{Binding Path=SaveCommand}

পরে:

// C# code
private void SaveObject() {
 // do something
}

// XAML
{BindTo SaveObject()}

আপনি এখানে লাইব্রেরিটি খুঁজে পেতে পারেন: http://www.simplygoodcode.com/2012/08/simpler-wpf-binding.html

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


2
এই ধরণের হাত ধরণের অনুশীলনগুলি এক্সএএমএল এর দুর্বলতা প্রদর্শন করে; উপায় খুব জটিল।
dudeNumber4

16

কিছু দরকারী বিট এবং টুকরা:

এটি বেশিরভাগ কোডে কীভাবে করবেন তা এখানে রয়েছে:

Binding b = new Binding();
b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, this.GetType(), 1);
b.Path = new PropertyPath("MyElementThatNeedsBinding");
MyLabel.SetBinding(ContentProperty, b);

আমি মূলত বিহাইন্ড রিলেটিভ সোর্স থেকে কোড পিছনে কোডটি অনুলিপি করেছি

এছাড়াও, উদাহরণগুলি হিসাবে এমএসডিএন পৃষ্ঠাটি বেশ ভাল: রিলেটিভসোর্স ক্লাস


5
আমার ডাব্লুপিএফের অস্পষ্ট মেমরিটি হ'ল কোডে বাঁধাই করা সাধারণত সেরা জিনিস নয়।
নাথান কুপার

12

আমি সিলভারলাইটে পিতামাতার উপাদানগুলির ডেটা কনটেক্সট অ্যাক্সেসের জন্য আরেকটি সমাধান পোস্ট করেছি যা আমার পক্ষে কাজ করে। এটি ব্যবহার করে Binding ElementName


10

আমি প্রতিটি উত্তর পড়িনি, তবে আমি কেবল কোনও বোতামের আপেক্ষিক উত্স কমান্ড বাঁধার ক্ষেত্রে এই তথ্যটি যুক্ত করতে চাই।

আপনি যখন কোনও আপেক্ষিক উত্সটি ব্যবহার করেন Mode=FindAncestor, তখন বাইন্ডিংটি অবশ্যই এর মতো হতে পারে:

Command="{Binding Path=DataContext.CommandProperty, RelativeSource={...}}"

আপনি যদি আপনার পথে ডেটা কনটেক্সট না যোগ করেন, কার্যকর করার সময় এটি সম্পত্তি পুনরুদ্ধার করতে পারে না।


9

খালি ডেটাগ্রিডে আমার জন্য এই প্যাটার্নটির ব্যবহারের এটি উদাহরণ।

<Style.Triggers>
    <DataTrigger Binding="{Binding Items.Count, RelativeSource={RelativeSource Self}}" Value="0">
        <Setter Property="Background">
            <Setter.Value>
                <VisualBrush Stretch="None">
                    <VisualBrush.Visual>
                        <TextBlock Text="We did't find any matching records for your search..." FontSize="16" FontWeight="SemiBold" Foreground="LightCoral"/>
                    </VisualBrush.Visual>
                </VisualBrush>
            </Setter.Value>
        </Setter>
    </DataTrigger>
</Style.Triggers>

6

যদি কোনও উপাদান চাক্ষুষ গাছের অংশ না হয়, তবে রিলেটিভসোর্স কখনই কাজ করবে না।

এই ক্ষেত্রে, আপনাকে থমাস লেভেস্কের নেতৃত্বে একটি আলাদা কৌশল চেষ্টা করতে হবে।

[ডাব্লুপিএফ] এর অধীনে তার ব্লগে সমাধান রয়েছে যখন ডেটা কনটেক্সট উত্তরাধিকার সূত্রে প্রাপ্ত হয় না তখন কীভাবে ডেটার সাথে বাঁধবেন । এবং এটি একেবারে উজ্জ্বলভাবে কাজ করে!

তাঁর ব্লগটি বন্ধ হওয়ার সম্ভাব্য ইভেন্টে পরিশিষ্ট এটিতে তার নিবন্ধের একটি আয়না কপি রয়েছে ।

দয়া করে এখানে মন্তব্য করবেন না, তার ব্লগ পোস্টে সরাসরি মন্তব্য করুন

পরিশিষ্ট এ: ব্লগ পোস্টের আয়না

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

আসুন একটি সাধারণ উদাহরণ দিয়ে উদাহরণস্বরূপ: আমরা একটি ডেটাগ্রিডে পণ্যগুলির একটি তালিকা প্রদর্শন করতে চাই। গ্রিডে, আমরা ভিউমোডেল দ্বারা প্রকাশিত একটি শোপ্রাইস সম্পত্তির মানের ভিত্তিতে মূল্য কলামটি প্রদর্শন করতে বা আড়াল করতে সক্ষম হতে চাই। সুস্পষ্ট পন্থাটি শোপ্রাইস সম্পত্তিটিতে কলামটির দৃশ্যমানতা আবদ্ধ করা:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding ShowPrice,
                Converter={StaticResource visibilityConverter}}"/>

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

System.Windows.Data ত্রুটি: 2: লক্ষ্য উপাদানটির জন্য পরিচালিত ফ্রেমওয়ার্কএলমেন্ট বা ফ্রেমওয়ার্ক কনটেন্টেলমেন্ট খুঁজে পাওয়া যায় না। BindingExpression: পাথ = ShowPrice; DataItem = নাল; টার্গেট উপাদান হ'ল ডেটাগ্রিডটেক্সটকালাম '(হ্যাশকোড = 32685253); লক্ষ্যযুক্ত সম্পত্তি হ'ল 'দৃশ্যমানতা' (টাইপ করুন 'দৃশ্যমানতা')

বার্তাটি বরং ক্রিপ্টিক, তবে অর্থটি আসলে বেশ সহজ: ডাব্লুপিএফ জানে না যে কোন ফ্রেমওয়ার্কএলমেন্টটি ডাটা কনটেক্সট পেতে ব্যবহার করবে, কারণ কলামটি ডেটাগ্রিডের ভিজ্যুয়াল বা যৌক্তিক গাছের নয় belong

আমরা পছন্দসই ফলাফল পাওয়ার জন্য বাঁধাইটি টুইঙ্ক করার চেষ্টা করতে পারি, উদাহরণস্বরূপ ডেটাগ্রিডে রিলেটিভসোর্স সেট করে:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding DataContext.ShowPrice,
                Converter={StaticResource visibilityConverter},
                RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>

বা আমরা শোপ্রাইসকে আবদ্ধ একটি চেকবক্স যুক্ত করতে পারি এবং উপাদানটির নাম উল্লেখ করে ইস্কেচড সম্পত্তিটিতে কলামের দৃশ্যমানতার সাথে বাঁধতে চেষ্টা করতে পারি:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding IsChecked,
                Converter={StaticResource visibilityConverter},
                ElementName=chkShowPrice}"/>

তবে এই কাজের কোনওটি কাজ করছে বলে মনে হয় না, আমরা সবসময় একই ফলাফল পাই ...

এই মুহুর্তে, দেখে মনে হচ্ছে যে একমাত্র কার্যকর উপায়টি কোড-ব্যাকডে কলামের দৃশ্যমানতা পরিবর্তন করা হবে, যা আমরা সাধারণত এমভিভিএম প্যাটার্নটি ব্যবহার করার সময় এড়াতে পছন্দ করি ... তবে আমি খুব শীঘ্রই হাল ছেড়ে দেব না, কমপক্ষে না consider বিবেচনা করার জন্য অন্যান্য বিকল্প রয়েছে 😉

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

ধারণাটি এমন একটি শ্রেণি তৈরি করা (আমি এটিকে কারণ হিসাবে খুব শীঘ্রই স্পষ্ট হওয়া উচিত বলে বাইন্ডিংপ্রক্সি বলেছিলাম) যা ফ্রিজেবলের উত্তরাধিকার সূত্রে প্রাপ্ত এবং ডেটা নির্ভরতার সম্পত্তি ঘোষণা করে:

public class BindingProxy : Freezable
{
    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

এরপরে আমরা ডেটাগ্রিডের সংস্থাগুলিতে এই শ্রেণীর একটি উদাহরণ ঘোষণা করতে পারি এবং ডেটা সম্পত্তিটি বর্তমান ডেটা কনটেক্সটে বাঁধাই করতে পারি:

<DataGrid.Resources>
    <local:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>

বাইন্ডিংয়ের উত্স হিসাবে এই বাইন্ডিংপ্রক্সি অবজেক্টটি (স্ট্যাটিক রিসোর্স দিয়ে সহজেই অ্যাক্সেসযোগ্য) নির্দিষ্টকরণের শেষ পদক্ষেপটি:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding Data.ShowPrice,
                Converter={StaticResource visibilityConverter},
                Source={StaticResource proxy}}"/>

নোট করুন যে বাঁধাই পথটি "ডেটা" দিয়ে উপসর্গ করা হয়েছে, যেহেতু পাথটি এখন বাইন্ডিংপ্রক্সি অবজেক্টের সাথে সম্পর্কিত।

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

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