5

में बुलाया जाएगा मैं एक ObservableCollection एक सूची बॉक्स और एक बूलियन संपत्ति एक बटन करने के लिए बाध्य करने के लिए बाध्य है। इसके बाद मैंने परिभाषित किया दो कनवर्टर्स, जो संग्रह पर चलता है और दूसरा बुलियन संपत्ति पर चलता है। जब भी मैं बूलियन संपत्ति को संशोधित करता हूं, कनवर्टर की कनवर्ट करें विधि को कॉल किया जाता है, जहां वही नहीं कहा जाता है यदि मैं अवलोकन संग्रह को संशोधित करता हूं। मैं क्या खो रहा हूँ??जब ValueConverter के Convert विधि WPF

आपके संदर्भ के लिए

स्निपेट्स,

XAML snipet,

<Window.Resources> 
    <local:WrapPanelWidthConverter x:Key="WrapPanelWidthConverter" /> 
    <local:StateToColorConverter x:Key="StateToColorConverter" /> 
</Window.Resources> 
<StackPanel> 
    <ListBox x:Name="NamesListBox" ItemsSource="{Binding Path=Names}"> 
     <ListBox.ItemsPanel> 
      <ItemsPanelTemplate> 
       <WrapPanel x:Name="ItemWrapPanel" Width="500" Background="Gray"> 
        <WrapPanel.RenderTransform> 
         <TranslateTransform x:Name="WrapPanelTranslatation" X="0" /> 
        </WrapPanel.RenderTransform> 
        <WrapPanel.Triggers> 
         <EventTrigger RoutedEvent="WrapPanel.Loaded"> 
          <BeginStoryboard> 
           <Storyboard> 
            <DoubleAnimation Storyboard.TargetName="WrapPanelTranslatation" Storyboard.TargetProperty="X" To="{Binding Path=Names,Converter={StaticResource WrapPanelWidthConverter}}" From="525" Duration="0:0:2" RepeatBehavior="100" /> 
           </Storyboard> 
          </BeginStoryboard> 
         </EventTrigger> 
        </WrapPanel.Triggers> 
       </WrapPanel> 
      </ItemsPanelTemplate> 
     </ListBox.ItemsPanel> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <Grid> 
        <Label Content="{Binding}" Width="50" Background="LightGray" /> 
       </Grid> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
    <Button Content="{Binding Path=State}" Background="{Binding Path=State, Converter={StaticResource StateToColorConverter}}" Width="100" Height="100" Click="Button_Click" /> 
</StackPanel> 

कोड के पीछे झलकी

public class WrapPanelWidthConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     ObservableCollection<string> aNames = value as ObservableCollection<string>; 
     return -(aNames.Count * 50); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 


public class StateToColorConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     bool aState = (bool)value; 
     if (aState) 
      return Brushes.Green; 
     else 
      return Brushes.Red; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

उत्तर

11

मुझे लगता है कि अगर Binding स्रोत अद्यतन किया गया है एक Binding में कनवर्टर हमेशा कहा जाता है और उस अद्यतन के बारे में सूचित करता है (DependencyProperty के रूप में याका उपयोग कर)। हालांकि, ObservableCollection कोई आइटम जोड़ा या निकाला गया है, तो PropertyChanged ईवेंट नहीं बढ़ाता है, लेकिन यह CollectionChanged ईवेंट बढ़ाता है। यदि संग्रह में कोई आइटम बदल जाता है तो यह कोई भी घटना नहीं उठाता है। यहां तक ​​कि अगर स्वयं आइटम PropertyChanged को जन्म देती है, इस संग्रह के बारे Binding अपडेट नहीं करेंगे क्योंकि Binding स्रोत आइटम, लेकिन संग्रह नहीं है।

मुझे डर है अपने दृष्टिकोण इस तरह से काम नहीं करेगा। आप इस कोई विकल्प नहीं ObservableCollection.Count के लिए सीधे बाँध सकता है और यह करने के लिए एक उचित गणित कनवर्टर जोड़ने उलट और गुणा करने के लिए, लेकिन Count संपत्ति परिवर्तन सूचना प्रदर्शन नहीं करता है, तो। मुझे लगता है कि आप अपने ViewModel या कोड-पीछे जो इन मामलों को संभालती में एक और संपत्ति प्रदान करने के लिए ... जब बाध्यकारी होता है या गुण परिवर्तन

+0

जब भी एक आइटम संग्रह में जोड़ा जाता है दूसरा बंधन का उपयोग वास्तव में मूल्यों को बदलने के लिए, ObservableCollection सदस्य CollectionModified ला रहा है घटना। जहां कनवर्टर्स तभी शुरू होते हैं जब संपत्ति संशोधित होती है। एक कामकाज के रूप में, कोई संग्रह संशोधित घटना के लिए सदस्यता ले सकता है और फिर संपत्ति परिवर्तनीय घटना को पर्यवेक्षण चयन के नाम के साथ बढ़ा सकता है। – sudarsanyes

+0

अभी आपके उत्तर में आया और मैंने भी इसका अनुमान लगाया। – sudarsanyes

+0

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

2

एक कनवर्टर कहा जाता है होगा। इसलिए जब भी बूलियन के मूल्य में परिवर्तन होता है तो आपके कनवर्टर को आपके बूलियन के लिए बुलाया जाता है। आपका संग्रह एक बार सेट होता है और वह तब होता है जब बाध्यकारी होता है और कनवर्टर का उपयोग किया जाता है। जब संग्रह के आंतरिक परिवर्तन (संग्रह को जोड़ा या हटा दिया जाता है) संपत्ति बदलती नहीं है (यानी आप एक नया संग्रह बाध्य नहीं कर रहे हैं) तो आपका कनवर्टर फिर से आग नहीं लगाता है।

एक दृश्य के मॉडल का उपयोग करें और अपने संग्रह लपेट और इस तरह की गणना को उस परिवर्तन सूचना को लागू करता है के रूप में एक और संपत्ति जोड़ें। आप इस रैपर वर्ग का उपयोग here से कर सकते हैं जो आपके संग्रह को लपेट देगा और वहां एक संपत्ति जोड़ना आसान होगा।

11

एक multibinding कनवर्टर इस मुद्दे पर काबू पाने के लिए इस्तेमाल किया जा सकता है। फिर आप संग्रह के साथ बाध्य कर सकते हैं। संपत्ति और संग्रह एक ही समय में संग्रह। गिनती फिर से मूल्यांकन पाने के लिए बाध्यकारी ट्रिगर किया जाएगा और फिर आप के रूप में आवश्यक

      <TextBlock IsHitTestVisible="false" 
           Margin="5,0" 
           TextTrimming="CharacterEllipsis" 
           VerticalAlignment="Center" 
           DockPanel.Dock="Left" > 
           <TextBlock.Text> 
            <MultiBinding Converter="{Resources:ListToStringConverter}"> 
             <Binding Path="List.Count" /> 
             <Binding Path="List" /> 
            </MultiBinding> 
           </TextBlock.Text> 
          </TextBlock> 
+0

इस विचार के लिए धन्यवाद! जबकि उपर्युक्त उत्तर मेरे लिए बिल्कुल काम नहीं करते थे, यह एक करता है। मुझे IValueConverter के बजाय IMultiValueConverter को लागू करने के लिए मेरे कनवर्टर को थोड़ा सा संशोधित करने की आवश्यकता है, और मुझे यह स्पष्ट करने की आवश्यकता है कि मेरा संग्रह कौन सा इंडेक्स होगा, लेकिन फिर यह ठीक है। – ygoe

+0

शानदार! उस विचार ने मुझे समय का एक गुच्छा बचा लिया। – gbc

+0

बढ़िया, धन्यवाद! – Aybe

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