मैं RelativeSource
WPF बाइंडिंग के साथ कैसे उपयोग कर सकता हूं और विभिन्न उपयोग-मामले क्या हैं?
मैं RelativeSource
WPF बाइंडिंग के साथ कैसे उपयोग कर सकता हूं और विभिन्न उपयोग-मामले क्या हैं?
जवाबों:
यदि आप वस्तु पर किसी अन्य संपत्ति के लिए बाध्य करना चाहते हैं:
{Binding Path=PathToProperty, RelativeSource={RelativeSource Self}}
यदि आप पूर्वजों पर संपत्ति प्राप्त करना चाहते हैं:
{Binding Path=PathToProperty,
RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}
यदि आप टेम्प्लेटेड पैरेंट पर प्रॉपर्टी प्राप्त करना चाहते हैं (तो आप कंट्रोलटेमप्लेट में 2 तरह से बाइंडिंग कर सकते हैं)
{Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}
या, छोटा (यह केवल OneWay बाइंडिंग के लिए काम करता है):
{TemplateBinding Path=PathToProperty}
AncestorType
।
FindAncestor
, इससे पहले AncestorType
, मुझे निम्न त्रुटि मिलती है: "RelativeSource FindAncestor मोड में नहीं है"। (वीएस २०१३, कम्यूनिटी वर्जन में)
{Binding Path=DataContext.SomeProperty, RelativeSource=...
:। यह मेरे लिए एक नौसिखिया के रूप में कुछ अप्रत्याशित था जब मैं एक DataTemplate के भीतर एक माता-पिता के DataContext को बांधने की कोशिश कर रहा था।
Binding RelativeSource={
RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemType}
}
...
के डिफ़ॉल्ट विशेषता RelativeSource
है Mode
संपत्ति। मान्य मूल्यों का एक पूरा सेट यहाँ ( MSDN से ) दिया गया है:
PreviousData आप पिछले डेटा मद (नहीं है कि नियंत्रण है कि डेटा आइटम शामिल है) डेटा आइटम की सूची में प्रदर्शित किया जा रहा आबद्ध होने देता है।
TemplatedParent उस तत्व को संदर्भित करता है जिससे टेम्पलेट (जिसमें डेटा-बाउंड तत्व मौजूद है) लागू किया जाता है। यह टेम्प्लेटबाइंडिंगटेक्स्टेंशन सेट करने के समान है और केवल तभी लागू होता है जब बाइंडिंग एक टेम्प्लेट के भीतर हो।
सेल्फ रिफ़रर्स उस एलिमेंट पर जिस पर आप बाइंडिंग सेट कर रहे हैं और आपको उसी एलीमेंट पर उस एलिमेंट की एक प्रॉपर्टी को दूसरी प्रॉपर्टी से बाँधने की अनुमति देता है।
FindAncestor डेटा-बाउंड तत्व की मूल श्रृंखला में पूर्वज को संदर्भित करता है। आप इसका उपयोग किसी विशिष्ट प्रकार के पूर्वज या उसके उपवर्गों को बांधने के लिए कर सकते हैं। यदि आप AncestorType और / या AncestorLevel को निर्दिष्ट करना चाहते हैं तो यह आपके द्वारा उपयोग की जाने वाली विधा है।
यहाँ MVVM आर्किटेक्चर के संदर्भ में एक अधिक दृश्य व्याख्या है:
{Binding Message}
(थोड़ा और सरल ...)
Path=DataContext.Message
काम करने के लिए बाध्य होने के लिए स्पष्ट रूप से सेट करना पड़ा । यह समझ में आता है, यह देखते हुए कि आप चौड़ाई / ऊंचाई / आदि के सापेक्ष संबंध कर सकते हैं। एक नियंत्रण की।
Bechir Bejaoui अपने लेख में WPF में RelativeSources के उपयोग के मामलों को उजागर करता है :
RelativeSource एक मार्कअप एक्सटेंशन है जो विशेष रूप से बाध्यकारी मामलों में उपयोग किया जाता है, जब हम किसी दिए गए ऑब्जेक्ट की संपत्ति को किसी अन्य ऑब्जेक्ट की स्वयं की संपत्ति में बाँधने का प्रयास करते हैं, जब हम किसी वस्तु की संपत्ति को उसके किसी अन्य रिश्तेदार माता-पिता से बाँधने की कोशिश करते हैं; कस्टम नियंत्रण विकास के मामले में और अंत में एक बाध्य डेटा की एक श्रृंखला का उपयोग करने के मामले में XAML के एक टुकड़े के लिए एक निर्भरता संपत्ति के मूल्य को बाध्य करते समय। उन सभी स्थितियों को रिश्तेदार स्रोत मोड के रूप में व्यक्त किया जाता है। मैं उन सभी मामलों को एक-एक कर उजागर करूंगा।
- मोड स्व:
इस मामले की कल्पना करें, एक आयत जो हम चाहते हैं कि इसकी ऊँचाई हमेशा इसकी चौड़ाई के बराबर हो, एक वर्ग जो कहता है। हम तत्व नाम का उपयोग करके ऐसा कर सकते हैं
<Rectangle Fill="Red" Name="rectangle" Height="100" Stroke="Black" Canvas.Top="100" Canvas.Left="100" Width="{Binding ElementName=rectangle, Path=Height}"/>
लेकिन इस उपरोक्त मामले में हम बाध्यकारी वस्तु के नाम को इंगित करने के लिए बाध्य हैं, अर्थात् आयत। हम RelativeSource का उपयोग करके एक ही उद्देश्य तक अलग-अलग तरीके से पहुंच सकते हैं
<Rectangle Fill="Red" Height="100" Stroke="Black" Width="{Binding RelativeSource={RelativeSource Self}, Path=Height}"/>
उस स्थिति के लिए हम बाध्यकारी वस्तु के नाम का उल्लेख करने के लिए बाध्य नहीं हैं और चौड़ाई हमेशा ऊँचाई के बराबर होगी जब भी ऊँचाई बदली जाएगी।
यदि आप चौड़ाई को ऊँचाई का आधा भाग बनाना चाहते हैं तो आप इसे बाइंडिंग मार्कअप एक्सटेंशन में एक कनवर्टर जोड़कर कर सकते हैं। चलिए अब एक और मामले की कल्पना करते हैं:
<TextBlock Width="{Binding RelativeSource={RelativeSource Self}, Path=Parent.ActualWidth}"/>
उपरोक्त मामले का उपयोग किसी दिए गए तत्व की दी गई संपत्ति को उसके प्रत्यक्ष माता-पिता में से किसी एक के लिए टाई करने के लिए किया जाता है क्योंकि यह तत्व एक संपत्ति रखता है जिसे माता-पिता कहा जाता है। यह हमें एक अन्य रिश्तेदार स्रोत मोड की ओर ले जाता है जो फाइंडअनस्टर एक है।
- मोड फाइंडअनॉन्सर
इस मामले में, किसी दिए गए तत्व की संपत्ति को उसके माता-पिता में से एक को कोरसे से जोड़ा जाएगा। उपरोक्त मामले के साथ मुख्य अंतर यह तथ्य है कि, संपत्ति के पूर्वजों के प्रकार और पूर्वजों की श्रेणी का निर्धारण करने के लिए यह आपके ऊपर है कि संपत्ति को टाई करें। वैसे XAML के इस टुकड़े के साथ खेलने की कोशिश करें
<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>
उपरोक्त स्थिति दो TextBlock तत्वों की है जो सीमाओं और कैनवास तत्वों की एक श्रृंखला के भीतर एम्बेडेड हैं जो उनके पदानुक्रमित माता-पिता का प्रतिनिधित्व करते हैं। दूसरा टेक्स्टब्लॉक दिए गए माता-पिता के नाम को रिश्तेदार स्रोत स्तर पर प्रदर्शित करेगा।
इसलिए AncestorLevel = 2 को AncestorLevel = 1 में बदलने का प्रयास करें और देखें कि क्या होता है। फिर पूर्वज के प्रकार को पूर्वज टाइप से बदलने का प्रयास करें।
प्रदर्शित पाठ पूर्वज प्रकार और स्तर के अनुसार बदल जाएगा। फिर अगर पूर्वज स्तर पूर्वज प्रकार के लिए उपयुक्त नहीं है तो क्या होगा? यह एक अच्छा सवाल है, मुझे पता है कि आप इसे पूछने वाले हैं। प्रतिक्रिया कोई अपवाद नहीं है और टेक्स्टबलॉक स्तर पर नोटिंग्स प्रदर्शित की जाएंगी।
- TemplatedParent
यह मोड किसी दिए गए ControlTemplate प्रॉपर्टी को उस कंट्रोल की प्रॉपर्टी से टाई करने में सक्षम करता है, जिस पर ControlTemplate लागू होता है। इस मुद्दे को अच्छी तरह से समझने के लिए यहाँ एक उदाहरण है
<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>
अगर मैं किसी दिए गए नियंत्रण के गुणों को उसके नियंत्रण टेम्पलेट पर लागू करना चाहता हूं तो मैं TemplatedParent मोड का उपयोग कर सकता हूं। इस मार्कअप एक्सटेंशन के लिए भी एक समान है जो टेम्प्लेटबाइंडिंग है जो पहले वाले के एक प्रकार का छोटा हाथ है, लेकिन टेम्प्लेटबाइंडिंग का मूल्यांकन टेम्पर्डपैरेंट के विपरीत संकलन समय पर किया जाता है जिसका मूल्यांकन पहले रन समय के बाद किया जाता है। जैसा कि आप bellow आकृति में टिप्पणी कर सकते हैं, पृष्ठभूमि और सामग्री बटन से नियंत्रण टेम्पलेट पर लागू होती है।
ListView
। जनक के ListView
नीचे 2 और स्तर हैं। इससे मुझे प्रत्येक में से प्रत्येक के बाद वी एम में डेटा गुजर रोकने ListView
केDataTemplate
WPF में RelativeSource
बाध्यकारी तीन properties
सेट करने के लिए उजागर करता है :
1. मोड: यह enum
चार मान हो सकते हैं:
ए। पिछलाडेटा (
value=0
): यहproperty
बाउंडके पिछले मान को असाइन करता हैख। TemplatedParent (
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}" />
2. पूर्वज: जब मोड FindAncestor
तब किस प्रकार के पूर्वज को परिभाषित करता है
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}
3. पूर्वज: जब मोडFindAncestor
तब पूर्वज का स्तर क्या है (यदि दो समान प्रकार के माता-पिता हैंvisual tree
)
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid, AncestorLevel=1}}
उपरोक्त सभी उपयोग के मामले हैं
RelativeSource binding
।
यह ध्यान देने योग्य है कि सिल्वरलाइट की इस सोच के लिए ठोकर खाने वालों के लिए:
सिल्वरलाइट केवल इन सब कमांड्स में से एक सबसे छोटा उपसमूह प्रदान करता है
मैंने WPF के बाइंडिंग सिंटैक्स को सरल बनाने के लिए एक लाइब्रेरी बनाई, जिसमें RelativeSource का उपयोग करना आसान है। यहाँ कुछ उदाहरण हैं। इससे पहले:
{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
'BEFORE' उदाहरण में ध्यान दें कि मैं विधि कोड को उपयोग करने के लिए उस कोड को पहले से ही अनुकूलित कर RelayCommand
रहा था जिसका उपयोग करके मैंने अंतिम बार WPF का मूल भाग नहीं देखा था। इसके बिना 'BEFORE' का उदाहरण और भी लंबा होता।
कुछ उपयोगी बिट्स और टुकड़े:
यहां बताया गया है कि यह अधिकतर कोड में कैसे किया जाता है:
Binding b = new Binding();
b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, this.GetType(), 1);
b.Path = new PropertyPath("MyElementThatNeedsBinding");
MyLabel.SetBinding(ContentProperty, b);
मैंने बड़े पैमाने पर कोड रिहाइंड में बाइंडिंग रिलेटिव सोर्स से इसे कॉपी किया ।
इसके अलावा, MSDN पृष्ठ बहुत अच्छा है जहाँ तक उदाहरण चलते हैं: RelativeSource Class
मैंने बस सिल्वरलाइट में एक मूल तत्व के डेटोनेक्स्ट को एक्सेस करने के लिए एक और समाधान पोस्ट किया जो मेरे लिए काम करता है। इसका उपयोग करता है Binding ElementName
।
मैंने हर उत्तर नहीं पढ़ा, लेकिन मैं सिर्फ एक बटन के रिश्तेदार स्रोत कमांड बंधन के मामले में इस जानकारी को जोड़ना चाहता हूं।
जब आप किसी रिश्तेदार स्रोत का उपयोग करते हैं Mode=FindAncestor
, तो बंधन जैसा होना चाहिए:
Command="{Binding Path=DataContext.CommandProperty, RelativeSource={...}}"
यदि आप अपने पथ में DataContext नहीं जोड़ते हैं, तो निष्पादन समय पर यह संपत्ति को पुनः प्राप्त नहीं कर सकता है।
यह इस पैटर्न के उपयोग का एक उदाहरण है जो मेरे लिए खाली डेटाग्रिड्स पर काम करता था।
<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>
यदि कोई तत्व दृश्य पेड़ का हिस्सा नहीं है, तो RelativeSource कभी काम नहीं करेगा।
इस मामले में, आपको एक अलग तकनीक का प्रयास करने की आवश्यकता है, जो थॉमस लेवेस्क द्वारा अग्रणी है।
उसके पास अपने ब्लॉग पर [WPF] के तहत समाधान है कि DataContext विरासत में नहीं मिलने पर डेटा को कैसे बांधें । और यह पूरी तरह से शानदार ढंग से काम करता है!
इस घटना की संभावना नहीं है कि उनका ब्लॉग नीचे है, अपेंडिक्स ए में उनके लेख की एक प्रति शामिल है ।
कृपया यहाँ टिप्पणी न करें, कृपया सीधे उनके ब्लॉग पोस्ट पर टिप्पणी करें ।
WPF में DataContext संपत्ति बेहद आसान है, क्योंकि यह स्वचालित रूप से उस तत्व के सभी बच्चों को विरासत में मिला है जहां आप इसे असाइन करते हैं; इसलिए आपको इसे उस प्रत्येक तत्व पर फिर से सेट करने की आवश्यकता नहीं है जिसे आप बांधना चाहते हैं। हालांकि, कुछ मामलों में DataContext सुलभ नहीं है: यह उन तत्वों के लिए होता है जो दृश्य या तार्किक पेड़ का हिस्सा नहीं हैं। फिर उन तत्वों पर संपत्ति बांधना बहुत मुश्किल हो सकता है ...
आइए एक सरल उदाहरण के साथ स्पष्ट करें: हम डेटाग्रिड में उत्पादों की एक सूची प्रदर्शित करना चाहते हैं। ग्रिड में, हम ViewModel द्वारा उजागर की गई ShowPrice संपत्ति के मूल्य के आधार पर मूल्य स्तंभ को दिखाने या छिपाने में सक्षम होना चाहते हैं। स्पष्ट दृष्टिकोण ShowPrice संपत्ति के लिए स्तंभ की दृश्यता को बांधने के लिए है:
<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
Visibility="{Binding ShowPrice,
Converter={StaticResource visibilityConverter}}"/>
दुर्भाग्य से, ShowPrice के मूल्य को बदलने का कोई प्रभाव नहीं है, और कॉलम हमेशा दिखाई देता है ... क्यों? यदि हम Visual Studio में आउटपुट विंडो को देखते हैं, तो हम निम्नलिखित लाइन को नोटिस करते हैं:
System.Windows.Data Error: 2: टारगेट एलिमेंट के लिए FrameworkElement या FrameworkContentElement गवर्निंग नहीं कर सकता। BindingExpression: पथ = ShowPrice; DataItem = बातिल; लक्ष्य तत्व 'डेटाग्रिड टेक्स्टकॉल्यूम' (हैशकोड = 32685253) है; लक्ष्य संपत्ति 'दृश्यता' है (टाइप 'दृश्यता')
संदेश बल्कि गूढ़ है, लेकिन अर्थ वास्तव में काफी सरल है: WPF को पता नहीं है कि DataContext प्राप्त करने के लिए कौन सा फ्रेमवर्क उपयोग करना है, क्योंकि स्तंभ DataGrid के दृश्य या तार्किक ट्री से संबंधित नहीं है।
हम वांछित परिणाम प्राप्त करने के लिए बाध्यकारी को ट्विक करने का प्रयास कर सकते हैं, उदाहरण के लिए डेटाग्रिड में RelativeSource की स्थापना करके:
<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
Visibility="{Binding DataContext.ShowPrice,
Converter={StaticResource visibilityConverter},
RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>
या हम ShowPrice से बंधे एक चेकबॉक्स को जोड़ सकते हैं, और तत्व के नाम को निर्दिष्ट करके IsChecked संपत्ति पर कॉलम दृश्यता को बांधने का प्रयास कर सकते हैं:
<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
Visibility="{Binding IsChecked,
Converter={StaticResource visibilityConverter},
ElementName=chkShowPrice}"/>
लेकिन इनमें से कोई भी वर्कअराउंड काम नहीं करता है, हम हमेशा एक ही परिणाम प्राप्त करते हैं ...
इस बिंदु पर, ऐसा लगता है कि केवल व्यवहार्य दृष्टिकोण कोड-पीछे में कॉलम दृश्यता को बदलना होगा, जिसे हम आमतौर पर एमवीवीएम पैटर्न का उपयोग करते समय बचना पसंद करते हैं ... लेकिन मैं इतनी जल्दी हार नहीं मानने वाला हूं, कम से कम नहीं जबकि there पर विचार करने के लिए अन्य विकल्प हैं
हमारी समस्या का समाधान वास्तव में काफी सरल है, और फ्रीज़ेबल वर्ग का लाभ उठाता है। इस वर्ग का प्राथमिक उद्देश्य उन वस्तुओं को परिभाषित करना है जिनके पास एक परिवर्तनीय और केवल-पढ़ने के लिए स्थिति है, लेकिन हमारे मामले में दिलचस्प विशेषता यह है कि फ़्रीज़ेबल ऑब्जेक्ट डेटाकोटेक्स्ट को तब भी विरासत में प्राप्त कर सकते हैं, जब वे दृश्य या तार्किक पेड़ में न हों। मैं सटीक तंत्र को नहीं जानता जो इस व्यवहार को सक्षम बनाता है, लेकिन हम इसका फायदा उठाने के लिए अपना बाध्यकारी कार्य करने जा रहे हैं ...
विचार एक वर्ग बनाने के लिए है (मैंने इसे उन कारणों के लिए बाइंडप्रॉक्सी कहा है जो बहुत जल्द स्पष्ट हो जाना चाहिए) जो फ्रीज़ेबल को विरासत में मिला है और डेटा निर्भरता संपत्ति घोषित करता है:
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 के संसाधनों में इस वर्ग का एक उदाहरण घोषित कर सकते हैं, और Data Data को वर्तमान DataContext में बाँध सकते हैं:
<DataGrid.Resources>
<local:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>
बाध्यकारी के लिए स्रोत के रूप में इस बाइंडप्रॉक्सी ऑब्जेक्ट (StaticResource के साथ आसानी से सुलभ) को निर्दिष्ट करने के लिए अंतिम चरण है:
<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
Visibility="{Binding Data.ShowPrice,
Converter={StaticResource visibilityConverter},
Source={StaticResource proxy}}"/>
ध्यान दें कि बाइंडिंग पथ "डेटा" के साथ उपसर्ग किया गया है, क्योंकि पथ अब बाइंडिंगप्रॉक्सी ऑब्जेक्ट के सापेक्ष है।
बाइंडिंग अब सही तरीके से काम करती है, और शोप्राइस प्रॉपर्टी के आधार पर कॉलम को ठीक से दिखाया या छिपाया गया है।