2009-04-26 19 views
5

मेरे पास मेरे ऐप में कुछ सूची बॉक्स अवलोकन करने योग्य चयनों से बंधे हैं, और यदि इसे हटाया जा रहा है तो मैं किसी आइटम को एनिमेट करना चाहता हूं।सूची बॉक्स में हटाए गए आइटम को एनिमेट करना

मुझे पहले से ही फ्रेमवर्क एलिमेंट.लोडेड ईवेंट का उपयोग कर अतिरिक्त आइटम एनिमेट करने के बारे में एक प्रश्न मिला है, लेकिन निश्चित रूप से यह अनलोडेड ईवेंट के साथ समान तरीके से काम नहीं करता है।

क्या ऐसा करने का कोई तरीका है जिस तरह से डेटामैप्लेट में उपयोग किया जा सकता है?

संपादित करें: मैंने अपने आइटमसोर्स में संग्रहChanged ईवेंट को जोड़ दिया है और मैन्युअल रूप से एनीमेशन लागू करने का प्रयास किया है। वर्तमान में यह इस तरह दिखता है:

ListBoxItem item = stack.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem; 
     item.LayoutTransform = new ScaleTransform(1, 1); 

    DoubleAnimation scaleAnimation = new DoubleAnimation(); 
    scaleAnimation.From = 1; 
    scaleAnimation.To = 0; 
    scaleAnimation.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 500)); 
    ScaleTransform transform = (ScaleTransform)item.LayoutTransform; 
    transform.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation); 

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

उत्तर

1

यह पता चला कि अगर मैं उन्हें हटाने से पहले एक घटना उठा रहा था, तो भी वे तुरंत हटा दिए जाएंगे। इसलिए जब मैं इसे एक अवलोकन योग्य ढेर के रूप में उपयोग कर रहा था, तो मैंने संग्रह में हटाए गए तत्व को छोड़कर इसे बाद में हटाकर इस पर काम किया। इस तरह:

public class ObservableStack<T> : ObservableCollection<T> 
{ 
    private T collapsed; 
    public event EventHandler BeforePop; 

    public T Peek() { 
     if (collapsed != null) { 
      Remove(collapsed); 
      collapsed = default(T); 
     } 
     return this.FirstOrDefault(); 
    } 

    public T Pop() { 
     if (collapsed != null) { Remove(collapsed); } 
     T result = (collapsed = this.FirstOrDefault()); 
     if (BeforePop != null && result != null) BeforePop(this, new EventArgs()); 
     return result; 
    } 

    public void Push(T item) { 
     if (collapsed != null) { 
      Remove(collapsed); 
      collapsed = default(T); 
     } 
     Insert(0, item); 
    } 
} 

सबसे अच्छा समाधान नहीं हो सकता है, लेकिन यह नौकरी करता है (कम से कम अगर मैं इसे केवल स्टैक के रूप में उपयोग करता हूं)।

+0

मेरे मामले में मेरे पास 3dparty INotifyCollectionChanged Obtics द्वारा कार्यान्वित किया गया है और कभी-कभी सर्वर साइड इवेंट्स द्वारा बदला जाता है ... मुझे नहीं पता कि आइटम को हटाने का तरीका कैसे एनिमेट करना है ... शायद मुझे इसे कस्टम इनोटिफ़ाइलेक्शन चेंज द्वारा लपेटना चाहिए और केवल देरी के लिए कस्टम इवेंट हटाने में देरी होनी चाहिए एनीमेशन। लेकिन यह केवल 1 आइटम प्रति घटना और प्रति एनीमेशन के लिए काम कर सकता है। INotifyCollectionChanged अनुबंध मानता है कि प्रत्येक इंस्टेंस घटनाओं द्वारा तुरंत अपने संग्रह को बदलता है और यदि मुझे देरी हो रही है - अगली घटना मुझे तत्व सूचकांक भेजती है मान लीजिए कि मैंने पिछले इंडेक्स द्वारा अपना संग्रह पहले से ही बनाए रखा है। –

1

मुझे इस समय एक कोड विंडो तक पहुंच नहीं है, इसलिए यह कफ से थोड़ी दूर है, लेकिन क्या आप फ्रेमवर्क एलीमेंट को अनलोडिंग ईवेंट के साथ बढ़ा सकते हैं, फिर उसे एक ऑब्जर्जेबल कोलेक्शन में कलेक्शन चेंज से शुरू कर सकते हैं। इसका मतलब है एक कस्टम ObservableColleciton और कस्टम फ्रेमवर्क एलिमेंट क्लास का उपयोग करना, लेकिन यह आपको जो चाहिए उसे पेश कर सकता है?

+0

पहले से ही अनलोड ईवेंट हैं। लेकिन वैसे भी यह एनीमेशन के लिए बेकार है, क्योंकि यह तत्व अस्तित्व का अंतिम उपाय है और इस घटना के बाद एनिमेट करने के लिए कुछ भी नहीं है। –

1

आप कमांड निष्पादन के दौरान दृश्य राज्यों को बदलने के लिए Present.Commands Fluent API का उपयोग कर सकते हैं। मैं animating जोड़ने और इसे यहाँ का उपयोग कर एक लिस्टबॉक्स में आइटम को हटाने का एक उदाहरण http://adammills.wordpress.com/2011/01/11/mvvm-animation-of-listbox-present-commands/

+0

यह उस मामले के लिए समाधान है जब उपयोगकर्ता इस कमांड को ट्रिगर करता है ... मेरे मामले में मेरे पास ओटोटिफ़ाइलेक्शन चेंज किया गया है जिसे ओबिक्स द्वारा कार्यान्वित किया गया है और सर्वर की तरफ बदल दिया गया है ... मुझे नहीं पता कि आइटम को हटाने का तरीका कैसे एनिमेट करना है ... –

2

मैं बाध्य आइटम के लिए एक IsRemoved संपत्ति जोड़कर इस हल पोस्ट किया है। ListViewItem कंटेनर टेम्पलेट में एक ईवेंट ट्रिगर तब बाध्य होता है जो हटाने के एनीमेशन को चलाता है जब यह बूल सत्य में बदल जाता है। समवर्ती रूप से, टास्क के साथ एक कार्य शुरू किया जाता है। डेले (एन) एनीमेशन की अवधि से मेल खाता है, और संग्रह से वास्तविक हटाने के साथ चलता है। ध्यान दें कि क्रॉस थ्रेड अपवाद से बचने के लिए सूची को हटाने के थ्रेड पर इस निष्कासन को प्रेषित करने की आवश्यकता है।

void Remove(MyItem item, IList<MyItem> list) 
{ 
    item.IsRemoved = true; 

    Task.Factory.StartNew(() => 
     { 
      Task.Delay(ANIMATION_LENGTH_MS); 
      Dispatcher.Invoke(new Action(() => list.Remove(item))); 
     }); 
} 
संबंधित मुद्दे