2011-04-29 18 views
5

मैं सीखने की कोशिश कर रहा हूं कि डब्ल्यूपीएफ बाइंडिंग और एमवीवीएम आर्किटेक्चर का उपयोग कैसे करें। मैं निर्भरता गुणों के साथ कुछ परेशानी में भाग रहा हूँ। मैंने डेटाकॉन्टेक्स्ट में निर्भरता प्रॉपर्टी को बाध्य करके दृश्य पर किसी आइटम की दृश्यता को नियंत्रित करने का प्रयास किया है, लेकिन यह काम नहीं करता है। कोई फर्क नहीं पड़ता कि मैंने नीचे दिए गए दृश्य मॉडल के निर्माता में GridVisible मान सेट किया है, जब मैं कोड चलाता हूं तो यह हमेशा दिखाई देता है।डब्ल्यूपीएफ डेटा बाइंडिंग आर्किटेक्चर प्रश्न

क्या कोई देख सकता है कि मैं कहां गलत हो रहा हूं?

सी # कोड (ViewModel):

public class MyViewModel : DependencyObject 
{ 
    public MyViewModel() 
    { 
     GridVisible = false; 
    } 

    public static readonly DependencyProperty GridVisibleProperty = 
    DependencyProperty.Register(
     "GridVisible", 
     typeof(bool), 
     typeof(MyViewModel), 
     new PropertyMetadata(false, 
       new PropertyChangedCallback(GridVisibleChangedCallback))); 

    public bool GridVisible 
    { 
     get { return (bool)GetValue(GridVisibleProperty); } 
     set { SetValue(GridVisibleProperty, value); } 
    } 

    protected static void GridVisibleChangedCallback(
     DependencyObject source, 
     DependencyPropertyChangedEventArgs e) 
    { 
     // Do other stuff in response to the data change. 
    } 
} 

XAML कोड (देखें):

<UserControl ... > 

    <UserControl.Resources> 
     <BooleanToVisibilityConverter x:Key="BoolToVisConverter" /> 
    </UserControl.Resources> 

    <UserControl.DataContext> 
     <local:MyViewModel x:Name="myViewModel" /> 
    </UserControl.DataContext> 

    <Grid x:Name="_myGrid" 
     Visibility="{Binding Path=GridVisible, 
      ElementName=myViewModel, 
      Converter={StaticResource BoolToVisConverter}}"> 

     <!-- Other elements in here --> 

    </Grid> 

</UserControl> 

मैं कई ट्यूटोरियल देखा है ऑनलाइन, और ऐसा लगता है जैसे मैं कर रहा हूँ जो मैंने पाया है उसका सही ढंग से अनुसरण करें। कोई विचार? धन्यवाद!

उत्तर

2

एलिमेंटनाम को अपने बाध्यकारी से बाहर ले जाएं, जो सही नहीं लगता है। करने के लिए इसे बदलें:

<Grid x:Name="_myGrid" 
     Visibility="{Binding Path=GridVisible, 
      Converter={StaticResource BoolToVisConverter}}"> 
+0

दरअसल मैंने आपके कोड को कॉपी किया और पाया कि यह एलिमेंटनाम के साथ और बिना बाध्यकारी के साथ काम करता है। आप उपयोगकर्ता नियंत्रण का उपयोग कर रहे हैं (यानी एक विंडो या अन्य उपयोगकर्ता नियंत्रण)? शायद वहां कुछ गड़बड़ है (कोड जिसमें आपने शामिल नहीं किया था)। – thornhill

+0

मैंने एलिमेंटनाम हटा दिया और यह अभी भी काम नहीं करता है। ऐसा लगता है कि आप सही हैं - शायद मेरे कोड के दूसरे भाग के साथ ऐसा कुछ करना है, न कि ऊपर पोस्ट किए गए स्वच्छता संस्करण। दुर्भाग्य से मैं वास्तविक कोड पोस्ट नहीं कर सकता क्योंकि यह काम के लिए है। – RobotNerd

+0

उस स्थिति में, जब आप अपना ऐप चला रहे हों और उस विंडो को खोलें जिसमें इस उपयोगकर्ता नियंत्रण शामिल है, तो इस के समान पाठ वाले किसी भी त्रुटि के लिए VisualStudio में अपनी आउटपुट विंडो देखें "BindingExpression पथ त्रुटि: 'GridVisible' प्रॉपर्टी पर नहीं मिली 'ऑब्जेक्ट ...... " उस संदेश की सामग्री आपको इससे आगे डीबग करने में मदद कर सकती है। क्षमा करें मैं आपको और अधिक मदद नहीं कर सकता। सौभाग्य। – thornhill

0

ViewModel DataContext के रूप में स्थापित करने की बात आसान रिश्तेदार बाइंडिंग सक्षम करने के लिए है, सभी बाइंडिंग जहां केवल Path निर्दिष्ट स्रोत के रूप में DataContext जो UserControl भर विरासत में मिलती है (जब तक यह है ले अन्यथा सेट करें, उदाहरण के लिए आइटम्स कंट्रोल के टेम्पलेटेड आइटमों में)

तो एक बार DataContext को UserControl पर सेट करने के बाद आप आमतौर पर वीएम को बाध्य करते समय किसी भी स्रोत को निर्दिष्ट नहीं करते हैं।

इसके अलावा मैं व्यक्तिगत रूप से ViewModels DependencyObject से विरासत नहीं होगा, क्योंकि यह परिचय धागे की आत्मीयता, यह भी DependencyProperties की बात विरल डेटा संरचनाओं अधिक के सभी में अनावश्यक क्षेत्रों बनाने नहीं द्वारा कुशल बना रही है (स्रोत ElementName, RelativeSource और Source कर रहे हैं) उन्हें (ViewModels सामान्य रूप से स्पैस के विपरीत हैं)।

+3

'INotifyPropertyChanged'' निर्भरता ऑब्जेक्ट 'का विकल्प है - अधिकांश व्यूमोडेल निर्भरता गुणों के बजाय इसका उपयोग करते हैं। –

1

अपना व्यू मॉडेल लागू करें IotifyProperty को निर्भर करता है बजाय निर्भरता ऑब्जेक्ट से विरासत प्राप्त करने के बजाय। इंटरफ़ेस को कार्यान्वित करें और संपत्ति के लिए अपने सेटर से PropertyChanged बढ़ाएं।

private bool gridVisible; 

    public bool GridVisible 
    { 
     get { return gridVisible; } 
     set 
     { 
      gridVisible = value; 
      OnPropertyChanged("GridVisible"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
+1

आपको अपने एक्सएएमएल में एलिमेंटनाम के साथ अपने वीएम को संदर्भित करने की आवश्यकता नहीं है, न ही आपको अपने वीएम को नाम देने की आवश्यकता है। जब आप इसे usercontrol पर असाइन करते हैं। डेटा कॉन्टेक्स्ट उपयोगकर्ता नियंत्रण के सभी बच्चों के लिए यह डिफ़ॉल्ट बाध्यकारी स्रोत बन जाता है। –

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