2009-05-10 8 views
14
के माध्यम से UserControl में कस्टम गुण स्थापना

मैं एक बहुत ही सरल UserControl कि है कहो - - सभी इरादों और उद्देश्यों के लिए पाठ बॉक्स से ज्यादा कुछ नहीं है: प्रपत्र परDataBinding

public partial class FooBox : UserControl 
{ 
    public static readonly DependencyProperty FooTextProperty = 
     DependencyProperty.Register("FooText", typeof(string), typeof(FooBox)); 

    public FooBox() 
    { 
     InitializeComponent(); 
    } 

    public string FooText 
    { 
     get { return textBlock.Text; } 
     set { textBlock.Text = value; } 
    } 
} 

<UserControl x:Class="Namespace.FooBox" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="300" Width="300"> 
    <Grid> 
     <TextBlock x:Name="textBlock" /> 
    </Grid> 
</UserControl> 

यह घोषित के रूप में:

<local:FooBox FooText="{Binding Name}" /> 

फ़ॉर्म का डेटाकॉन्टेक्स्ट उस ऑब्जेक्ट पर सेट है जिसमें नाम संपत्ति है। लेकिन यह मेरे लिए काम नहीं कर रहा है। मैं क्या खो रहा हूँ?

उत्तर

5

वास्तविक समस्या को हल करता है कि मैं डब्ल्यूपीएफ ढांचे को अपनी सार्वजनिक संपत्ति सेट करने की उम्मीद कर रहा था, जहां मेरा कोड परिवर्तनों का जवाब देगा और नए मूल्य के अनुसार प्रस्तुत करेगा। ऐसा नहीं। क्या WPF करता है SetValue() को सीधे कॉल करता है और पूरी तरह से सार्वजनिक संपत्ति को रोकता है। मुझे क्या करना था DependencyPropertyDescriptor.AddValue का उपयोग करके संपत्ति परिवर्तन अधिसूचनाएं प्राप्त हुईं और इसका जवाब दिया। ऐसा कुछ दिखता है (सीटीआर के अंदर):

var dpd = DependencyPropertyDescriptor 
    .FromProperty(MyDependencyProperty, typeof(MyClass)); 
dpd.AddValueChanged(this, (sender, args) => 
{ 
    // Do my updating. 
}); 
+4

यह भी ध्यान रखें कि निर्भरता गुणों के लिए पंजीकरण विधि में ओवरलोड हैं जो ईवेंट हैंडलर स्वीकार कर सकते हैं जिन्हें संपत्ति बदल रही है या बदल गई है। यह आपके पास मौजूद तर्क को रखने का एक स्थान हो सकता है। –

19

निर्भरता प्रॉपर्टी में एक संपत्ति घोषणा के "प्राप्त" और "सेट" भागों को वास्तव में डब्ल्यूपीएफ की डाटाबेसिंग सिस्टम द्वारा नहीं कहा जाता है - वे अनिवार्य रूप से केवल कंपाइलर को संतुष्ट करने के लिए हैं।

इसके बजाय, इस तरह देखने के लिए अपनी संपत्ति घोषणा बदलने के लिए:

public string FooText 
{ 
    get { return (string)GetValue(FooTextProperty); } 
    set { SetValue(FooTextProperty, value); } 
} 

... और करने के लिए अपने XAML:

<UserControl ... 
    x:Name="me"> 
    <Grid> 
     <TextBlock Text="{Binding FooText,ElementName=me}" /> 
    </Grid> 
</UserControl> 

अब आप अपने TextBox.Text बस "FooText" करने के लिए सीधे बांधता संपत्ति, ताकि आप बदले में FooText प्रॉपर्टी को "नाम" में बाध्य कर सकें जैसे आप वर्तमान में कर रहे हैं।

एक और तरीका टेक्स्टब्लॉक को बांधना है। एक रिलेटिवसोर्स बाइंडिंग के आगे जो फूटेक्स्ट प्रॉपर्टी को "फूबॉक्स" के पहले पूर्वजों पर पाता है, लेकिन मुझे पता चला है कि यह केवल एक आंतरिक x को नियंत्रण देने से अधिक जटिल है: तत्व बाध्यकारी नाम और उपयोग।

+0

मैं आपको वोट दूंगा क्योंकि आपने मुझे जो खो रहा था उसके करीब आने में मदद की थी। लेकिन असली परीक्षण का पर्दाफाश करने के लिए यहां मेरा टेस्ट केस बहुत आसान था। मेरा जवाब देखें – xanadont

संबंधित मुद्दे