2012-10-19 13 views
6

मैं WinRT XAML ऐप में एक कस्टम पैनल बनाने की मूल बातें सीखने की कोशिश कर रहा हूं। मैंने एक संलग्न निर्भरता संपत्ति परिभाषित की है और यह उम्मीद के अनुसार काम कर रहा है सिवाय इसके कि मैं यह समझ नहीं सकता कि कंटेनर की व्यवस्था या माप को ट्रिगर करने के लिए किसी बच्चे तत्व के लिए संपत्ति के कॉलबैक को कैसे प्राप्त किया जाए।एक कंटेनर को कैसे पता चलता है जब किसी बच्चे ने अमान्य आर्टेंज कहा है?

बच्चे के कंटेनर को यह बताने का उचित तरीका क्या है कि व्यवस्था और माप को फिर से बुलाया जाना चाहिए? मेरे डब्ल्यूपीएफ 4 अनलेश बुक में वे फ्रेमवर्कप्रॉपर्टी मेटाडेटाऑप्शन का उपयोग करते हैं। अफेक्ट्सपेरेंट्रेंज लेकिन यह WinRT में उपलब्ध नहीं प्रतीत होता है।

public class SimpleCanvas : Panel 
{ 
    #region Variables 
    #region Left Property 
    public static double GetLeft(UIElement element) 
    { 
     if (element == null) 
     { 
      throw new ArgumentNullException("element"); 
     } 

     object value = element.GetValue(LeftProperty); 
     Type valueType = value.GetType(); 
     return Convert.ToDouble(value); 
    } 

    public static void SetLeft(UIElement element, double value) 
    { 
     if (element == null) 
     { 
      throw new ArgumentNullException("element"); 
     } 

     element.SetValue(LeftProperty, value); 
    } 

    public static readonly DependencyProperty LeftProperty = 
     DependencyProperty.RegisterAttached("Left", typeof(double), typeof(SimpleCanvas), 
     new PropertyMetadata(0, OnLeftPropertyChanged)); 

    public static void OnLeftPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) 
    { 
     UIElement element = (UIElement)source; 
     // This doesn't cause ArrangeOverride below to be called 
     element.InvalidateArrange(); 
    } 
    #endregion 

    #region Top Property 
    public static double GetTop(UIElement element) 
    { 
     if (element == null) 
     { 
      throw new ArgumentNullException("element"); 
     } 

     object value = element.GetValue(TopProperty); 
     return (value == null) ? 0 : (double)value; 
    } 

    public static void SetTop(UIElement element, double value) 
    { 
     if (element == null) 
     { 
      throw new ArgumentNullException("element"); 
     } 

     element.SetValue(TopProperty, value); 
    } 

    public static readonly DependencyProperty TopProperty = 
     DependencyProperty.RegisterAttached("Top", typeof(double), typeof(SimpleCanvas), 
     new PropertyMetadata(0, OnTopPropertyChanged)); 

    public static void OnTopPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) 
    { 
     UIElement element = (UIElement)source; 
     // This doesn't cause ArrangeOverride below to be called 
     element.InvalidateArrange(); 
    } 
    #endregion 
    #endregion 

    public SimpleCanvas() 
    { 

    } 

    #region Methods 
    protected override Size MeasureOverride(Size availableSize) 
    { 
     foreach (UIElement child in this.Children) 
     { 
      child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); 
     } 

     return new Size(0, 0); 
    } 

    protected override Size ArrangeOverride(Size finalSize) 
    { 
     foreach (UIElement child in this.Children) 
     { 
      double x = 0; 
      double y = 0; 

      double left = GetLeft(child); 
      double top = GetTop(child); 

      if (!double.IsNaN(left)) 
      { 
       x = left; 
      } 
      if (!double.IsNaN(top)) 
      { 
       y = top; 
      } 

      child.Arrange(new Rect(new Point(x, y), child.DesiredSize)); 
     } 

     return finalSize; 
    } 
    #endregion 
} 

उत्तर

0

यदि अमान्य अलर्ट अकेले काम नहीं करता है तो आप अमान्य मेटाइज़र या अपडेटलेआउट को भी आजमा सकते हैं।

+1

InvalidateArrange(), InvalidateMeasure(), और UpdateLayout(), लेकिन ArrangeOverride() और न ही MeasureOverride() में न breakpoints में बदला गया कॉलबैक में मारा जाता है: मैं माता-पिता के ढेर ऊपर यात्रा और सब कुछ प्राप्त नहीं द्वारा समस्या हल बर्तन। – user263619

+0

शायद यह जांचता है कि क्या लेआउट गुणों में से कोई भी बदल गया है और यदि कोई नहीं है - यह इसे कॉल नहीं करता है। आपको तब कुछ लेआउट गुणों को बदलने की आवश्यकता हो सकती है, लेकिन यह मौजूदा बाइंडिंग को तोड़ सकता है। –

3

मुझे पार्टी के लिए देर हो चुकी है, लेकिन मैं एक ही दिशा में गया और उसी मुद्दे का सामना किया। मेरा समाधान यहाँ है।

अपने कॉलबैक में आप चाइल्ड तत्व आप के लिए आप संपत्ति संलग्न पर InvalidateArrange फोन:

public static void OnTopPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) 
{ 
    UIElement element = (UIElement)source; 
    // This doesn't cause ArrangeOverride below to be called 
    element.InvalidateArrange(); 
} 

लेकिन क्या तुम सच में, पैनल रद्द करना चाहिए ताकि आप कोड को बदलने के द्वारा:

public static void OnTopPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) 
{ 
    UIElement panel= VisualTreeHelper.GetParent(source) as UIElement; 
    if(panel != null)  
     panel.InvalidateArrange(); 
} 

और यह काम करना चाहिए (मेरे लिए किया)।

+0

इसे उत्तर के रूप में चिह्नित किया जाना चाहिए। – Yawar

+0

मुझे विश्वास नहीं है कि मैंने इसे समझने की कोशिश कर दो दिनों का बेहतर हिस्सा बिताया है ... बहुत बहुत धन्यवाद! – Gaet

0

मुझे इस समस्या को बाल नियंत्रण के साथ था जो माता-पिता नियंत्रण के FontSize पर निर्भर था।

static MyControl() 
    { 
     // replace base implementation of the dependent property 
     FontSizeProperty.OverrideMetadata(typeof(Scalar), 
      new FrameworkPropertyMetadata(SystemFonts.MessageFontSize, FrameworkPropertyMetadataOptions.Inherits, OnMeasureInvalidated)); 
    } 

    private static void OnMeasureInvalidated(DependencyObject sender, DependencyPropertyChangedEventArgs args) 
    { 
     // recurse over parent stack 
     while (true) 
     { 
      var parent = VisualTreeHelper.GetParent(sender) as UIElement; 
      if (parent == null) return; // break on root element 
      parent.InvalidateMeasure(); 
      sender = parent; 
     } 
    }