2010-03-12 12 views
5

[मूल रूप]
मैं एक ListBox जो अपने ItemsSource (इस कोड में पीछे पर विंडो के रूप में बनाया जाता है किया जाता है) एक ObservableCollection को डेटाबाउंड है की है।DataTrigger पुनः मूल्यांकन करने नहीं के बाद संपत्ति में परिवर्तन

usercontrol.xaml

<ListBox x:Name="communicatorListPhoneControls" 
     ItemContainerStyle="{StaticResource templateForCalls}"/> 

App.xaml

<Style x:Key="templateForCalls" TargetType="{x:Type ListBoxItem}"> 
    <Setter Property="ContentTemplate" Value="{StaticResource templateRinging}"/> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding Path=hasBeenAnswered}" Value="True"> 
       <Setter Property="ContentTemplate" Value="{StaticResource templateAnswered}"/> 
      </DataTrigger> 
     </Style.Triggers> 
    </Setter> 
</Style> 

जब ObservableCollection एक वस्तु के साथ अद्यतन किया जाता है, इस ListBox में प्रकट होता है: ListBox उसके बाद निम्न DataTemplate आइटम के खिलाफ सौंपा है सही प्रारंभिक DataTemplate के साथ, हालांकि hasBeenAnswered संपत्ति true पर सेट की गई है (जब मैं डीबगिंग कर सकता हूं संग्रह सही है) DataTrigger पुन: मूल्यांकन नहीं करता है और फिर ListBox को सही DataTemplate का उपयोग करने के लिए अद्यतन करता है।

मैंने अपने ऑब्जेक्ट में INotifyPropertyChanged ईवेंट लागू किया है, और यदि टेम्पलेट में एक मान से जुड़ा हुआ है, तो मैं मान अपडेट देख सकता हूं। यह सिर्फ DataTrigger सही टेम्पलेट का पुनर्मूल्यांकन और परिवर्तन नहीं करेगा।

मैं, पता DataTrigger बाध्यकारी सही है क्योंकि अगर मैं विंडो बंद करें और इसे फिर से खोलने के लिए, इसे सही ढंग से दूसरे DataTemplate लागू होगा क्योंकि hasBeenAnsweredtrue को तैयार है।

[संपादित करें 1]
Timores द्वारा की गई टिप्पणियों से इसे जारी रखते हुए मैंने कोशिश की है:

usercontrol.xaml

<ListBox x:Name="communicatorListPhoneControls" 
     ItemTemplate="{StaticResource communicatorCallTemplate}"/>` 

App.xaml:

<DataTemplate x:Key="communicatorCallTemplate"> 
    <Label x:Name="test">Not answered</Label> 
     <DataTemplate.Triggers> 
      <DataTrigger Binding="{Binding Path=hasBeenAnswered}" Value="True"> 
       <Setter TargetName="test" Property="Background" Value="Blue"/> 
      </DataTrigger>  
     </DataTemplate.Triggers> 
    </Label> 
</DataTemplate> 

अब क्या होता है पहले उदाहरण के समान होता है, जब "उत्तर नहीं दिया गया" लेबल शो में कोई कॉल आता है (एक प्रति कॉल जो कि मौजूद है, एक सूची बॉक्स है - आम तौर पर जब खिड़की लोड होती है तो कोई कॉल नहीं होगी), कॉल का उत्तर दिया जाता है और प्रोपर्टी hasBeenAnswered सत्य पर सेट किया गया है, फिर भी "उत्तर नहीं दिया गया" वही रहता है। अगर मैं खिड़की को बंद करता हूं, और इसे दोबारा खोलता हूं (संपत्ति के साथ सक्रिय कॉल के साथ अभी भी सही जवाब दिया गया है) पृष्ठभूमि फिर नीली है। तो यह मुझे दिखाई देगा जैसे डेटाैट्रिगर बस चल रहा है, जब तक कि खिड़की फिर से नहीं चल जाती।

उत्तर

1

उदाहरण में मुझे अजीब लगता है कि आप आइटम टेम्पलेट के बजाय आइटमकंटनर स्टाइल का उपयोग कर रहे हैं।

ItemContainerStyle ListBoxItem पर लागू होता है जिसमें आपके आइटम स्रोत में प्रत्येक तत्व शामिल होता है। ListboxItem में hasBeenAnswered संपत्ति नहीं है, इसलिए मुझे नहीं लगता कि बाइंडिंग कैसे काम कर सकती है।

मैं आपके सूची बॉक्स में डेटा प्रकार के लिए डेटा टेम्पलेट बनाने और अपने templateAnswered शैली में समान परिवर्तन करने के लिए ट्रिगर्स का उपयोग करने का सुझाव देता हूं।

संपादित करें: ओपी के बाद आइटम टेम्पलेट के सुझाव का उपयोग किया गया।

मैंने उदाहरण को पुन: उत्पन्न करने की कोशिश की, और यह मेरे लिए ठीक काम करता है। यहाँ मेरी XAML है (शैली पर ध्यान न दें, यह सिर्फ एक उदाहरण है):

नहीं दिए

<ListBox x:Name="communicatorListPhoneControls" 
      ItemTemplate="{StaticResource communicatorCallTemplate}"/> 

    <Button Margin="0,20,0,0" Click="OnToggleAnswer" Content="Toggle answer status" /> 
</StackPanel> 

और code- में पीछे:

public partial class Window1 : Window { 

    public Window1() { 
     InitializeComponent(); 

     List<PhoneCall> lpc = new List<PhoneCall>() 
     {new PhoneCall(), new PhoneCall(), new PhoneCall(), new PhoneCall()}; 

     communicatorListPhoneControls.ItemsSource = lpc; 
    } 

    private void OnToggleAnswer(object sender, RoutedEventArgs e) { 

     object o = communicatorListPhoneControls.SelectedItem; 

     if (o != null) { 

      PhoneCall pc = (PhoneCall) o; 
      pc.hasBeenAnswered = ! pc.hasBeenAnswered; 
     } 
    } 
} 

public class PhoneCall : INotifyPropertyChanged { 

    private bool _answered; 


    public bool hasBeenAnswered { 
     get { return _answered; } 
     set { 
      if (_answered != value) { 
       _answered = value; 
       FirePropertyChanged("hasBeenAnswered"); 
      } 
     } 
    } 

    private void FirePropertyChanged(string propName) { 

     if (PropertyChanged != null) { 

      PropertyChanged(this, new PropertyChangedEventArgs(propName)); 
     } 
    } 
    public event PropertyChangedEventHandler PropertyChanged; 
} 

क्या आप इसे पुन: पेश करने और अपने कोड से तुलना करने का प्रयास कर सकते हैं? नोट: PropertyChanged को दिए गए संपत्ति नाम में सबसे छोटी त्रुटि आपके व्यवहार की व्याख्या कर सकती है। ट्रिगर सही संपत्ति पर आधारित हो सकता है, लेकिन अधिसूचना में गलत वर्तनी का नाम हो सकता है।

+0

मैंने इसे कार्यान्वित करने का प्रयास किया है, लेकिन यह अभी भी लागू हो रहा है अगर मैं खिड़की बंद कर दूं और इसे फिर से खोलूं। मैं इसे दिखाने के लिए आंतरिक टिप्पणी में संशोधन करूंगा। आपके पास कोई विचार है? –

+0

अहह्ह! मुझे यह मिल गया है, मेरी खुद की बेवकूफ वर्तनी, आप सही थे, INOTifyProperyChanged में मैंने "हैबिन उत्तर दिया" के बजाय "हैबिन उत्तर दिया" था। निजी बूलियन _hasBeen उत्तर दिया; सार्वजनिक बूलियन हैबिन अनुत्तरित { {वापसी _hasBeen उत्तर दिया गया; } सेट { _hasBeenAnssej = value; नोटिफ़ाईप्रॉपर्टी चेंज ("हैबिन उत्तर दिया गया"); } } } आपकी सभी मदद के लिए धन्यवाद। –

+0

आपका स्वागत है। लेकिन मैं मूल रूप से गलत था, यानी ItemContainerStyle में DataContext वास्तव में आइटम है, ListBoxItem नहीं। मैंने अपना उदाहरण अपने मूल प्रश्न की तरह अधिक होने के लिए बदल दिया, और यह भी काम करता है। – Timores

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

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