सवाल एक्सएएमएल में स्वयं / 'यह' के लिए बाध्यकारी


सरल WPF / XAML प्रश्न। एक्सएएमएल में, मैं किसी दिए गए संदर्भ में स्वयं / इस ऑब्जेक्ट को कैसे संदर्भित करूं? एक मुख्य खिड़की, एक नियंत्रण, और खिड़की की एक कोडित सी # संपत्ति के साथ एक बहुत ही बुनियादी ऐप में, मैं खिड़की की हाथ कोडित संपत्ति को नियंत्रण की एक संपत्ति बांधना चाहता हूं।

कोड में, यह बहुत आसान है - विंडो के कन्स्ट्रक्टर में, मैंने इसे जोड़ा:

Binding bind = new Binding();
bind.Source = this;
bind.Path = new PropertyPath("ButtonWidth");
button1.SetBinding(WidthProperty, bind);

जाहिर है, मेरे पास बटनविड्थ नामक एक संपत्ति है, और बटन 1 नामक एक नियंत्रण है। मैं एक्सएएमएल में ऐसा करने का तरीका नहीं समझ सकता। निम्नलिखित उदाहरणों के विभिन्न प्रयासों ने काम नहीं किया है:

<Button x:Name="button1" Width="{Binding Source=Self Path=ButtonWidth}"/>

<Button x:Name="button1" Width="{Binding RelativeSource={RelativeSource Self} Path=ButtonWidth}"/> 

आदि

धन्यवाद


44
2017-10-01 09:01


मूल




जवाब:


सबसे पहले अपने बाध्यकारी में सापेक्ष स्रोत और पथ के बीच एक अल्पविराम का उपयोग करें:

<Button x:Name="button1" Width="{Binding RelativeSource={RelativeSource Self}, 
                                Path=ButtonWidth}"/> 

दूसरा, सापेक्ष स्रोत बटन से बांधता है। बटन में बटनविड्थ नामक कोई संपत्ति नहीं है। मुझे लगता है कि आपको अपने माता-पिता के नियंत्रण में बंधने की ज़रूरत है।

तो इस सापेक्ष स्रोत बाध्यकारी कोशिश करें:

<Button x:Name="button1" Width="{Binding RelativeSource=
    {RelativeSource FindAncestor, AncestorType={x:Type YourNamespace:YourParentControl}}, 
    Path=ButtonWidth}"/> 

69
2017-10-01 09:07



इस पोस्ट के लिए बहुत - बहुत धन्यवाद। इसने मेरी बहुत मदद की! मैं अब 3 घंटे एक अच्छा समाधान खोज रहा हूं। - Mr Tangjai
मेरे पास डेटाग्रिड है, जहां उपयोगकर्ता अपने इनलाइन कॉन्टेक्स्टमेनू के मेनू इटिम के कमांड को इनपुट इनपुटिंग की कीबाइंडिंग के माध्यम से एक्सेस करता है जिसका कमांड पैरामीटर = "{बाध्यकारी एलिमेंटनाम = माईडाटा ग्रिड, पथ = चयनित इटम्स}", यह चयनित इटम्स को बाउंड आईसीओएमएंड में पास कर देगा। हालांकि, अगर कॉन्टेक्स्टमेनू के माध्यम से इसका उपयोग किया जाता है तो शून्य पास हो जाता है। मैंने कमांड पैरामीटर = "{बाइंडिंग चयनित इटम्स}", "{बाइंडिंग एलिमेंटनाम = माईडाटा ग्रिड, पथ = चयनित इटम्स}", "{बाध्यकारी सापेक्ष स्रोत = {सापेक्ष स्रोत खोज पूर्वजों, पूर्वजों टाइप = {x: डेटाग्रिड टाइप करें}}, पथ = चयनित इटम्स}" । मैंने कमान से पहले कमांड पैरामीटर सेट किया था। - Tom


रिलेवेटसोर्स से निपटने के लिए मुझे एक तरह से मिलता है और जैसे रूट XAML तत्व का नाम देना है:

<Window x:Class="TestApp2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    x:Name="_this"
    >
    <Grid>
        <Button x:Name="button" Width="{Binding ElementName=_this,Path=ButtonWidth}" />
    </Grid>
</Window>

यदि आप डेटाकॉन्टेक्स्ट सेट करना चाहते हैं तो आप यह भी कर सकते हैं:

<Window x:Class="TestApp2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    x:Name="_this"
    >
    <Grid DataContext="{Binding ElementName=_this}">        
        <Button x:Name="button" Width="{Binding Path=ButtonWidth}" />
    </Grid>
</Window>

मुझे लगता है कि यह सापेक्ष स्रोत बाध्यकारी की सभी जटिलताओं को याद रखने के लिए एक अच्छी चाल है।


27
2017-11-29 22:08





मुझे लगता है कि आप जो खोज रहे हैं वह यह है:

<Window x:Class = "blah blah all the regular stuff"

DataContext="{Binding RelativeSource={RelativeSource Self}}"

>

25
2017-11-07 17:48



सत्यापित अभी भी <10> मुख्य तत्व में विंडोज 10 ऐप पर काम करता है। - Lavamantis


नामकरण के साथ समस्या XAML मूल तत्व यह है कि, यदि आप अपने प्रोजेक्ट की सभी जड़ों के लिए एक ही नाम (यानी, "_this", "रूट", आदि) का उपयोग करने की आदत में आते हैं, तो नेस्टेड टेम्पलेट्स में देर से बाध्यकारी गलत तत्व तक पहुंच सकता है । ऐसा इसलिए है क्योंकि, कब {Binding}  ElementName=... एक में प्रयोग किया जाता है Template, चलने के द्वारा रनटाइम पर नाम हल किए जाते हैं NameScope पहला मैच मिलने तक पेड़।

क्लिंट का समाधान रूट तत्व का नामकरण से बचाता है, लेकिन यह मूल तत्व को अपने आप में सेट करता है DataContext, जो डाटाकॉन्टेक्स्ट की आवश्यकता है, डेटा के लिए एक विकल्प नहीं हो सकता है। यह केवल उस तक पहुंच प्रदान करने के उद्देश्य से तत्व पर एक और बाध्यकारी पेश करने के लिए थोड़ा भारी हाथ लगता है। बाद में, अगर पहुंच की आवश्यकता नहीं है, तो {Binding} अव्यवस्था बन जाएगी: पहुंच के लिए जिम्मेदारी सही ढंग से लक्ष्य और बाध्यकारी से संबंधित है।

तदनुसार, XAML रूट तत्व को नाम देने के बिना यहां एक सरल मार्कअप एक्सटेंशन है:

using System.Xaml;
using System.Windows.Markup;

public sealed class XamlRootExtension : MarkupExtension
{
    public override Object ProvideValue(IServiceProvider sp)
    {
        var rop = sp.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
        return rop == null ? null : rop.RootObject;
    }
};

XAML:

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:global="clr-namespace:">

    <TextBlock Text="{Binding Source={global:XamlRoot},Mode=OneTime}" />

</Window>

परिणाम:

enter image description here


N.B.

स्पष्टता के लिए, नहीं clr-namespace प्रयोग किया जाता है, लेकिन ध्यान दें कि यहां दिखाए गए एक्सएएमएल वास्तव में पहुंचने के लिए काम करता है global नेमस्पेस (हालांकि वीएस2013 डिजाइनर शिकायत करता है)


3
2017-12-19 22:18





दुर्भाग्यवश, "ElementName = .." के साथ मूल तत्व का नामकरण यूडब्ल्यूपी के साथ एकमात्र तरीका है जैसा कि {RelativeSource Self} समर्थित नहीं है।

विचित्र रूप से पर्याप्त, यह तब भी काम करता है जब नाम लेआउट में ओवरराइड होता है, उदा।

<UserControl x:Class="Path.MyClass" x:Name="internalName">
   <Border Background={Binding Path=Background, ElementName=internalName}" ...

फिर

<Page>
   <local:MyClass x:Name=externalName />

</Page>

बीटीडब्लू, विंडोज 10 ने एक त्रुटि तय की (विंडोज 8.1 पर मौजूद), जब एक ही लेआउट में विभिन्न तत्वों के लिए समान आंतरिक नाम का उपयोग किया जाता है।

फिर भी, मैं {RelativeSource Self} का उपयोग करना पसंद करूंगा, क्योंकि यह मेरे लिए अधिक तार्किक और सुरक्षित प्रतीत होता है।


0
2018-02-15 02:17