Ich versuche, die Grundlagen zum Erstellen eines benutzerdefinierten Bereichs in einer WinRT XAML App zu lernen. Ich habe eine angefügte Abhängigkeitseigenschaft definiert und funktioniert wie erwartet, außer dass ich nicht herausfinden kann, wie der Rückruf der Eigenschaft für ein untergeordnetes Element abgerufen wird, um die Anordnung oder das Maß des Containers auszulösen.Wie weiß ein Container, wenn ein Kind InvalidateArrange aufgerufen hat?
Was ist der richtige Weg, damit ein Kind seinen Container wissen lässt, dass arrange und measure erneut aufgerufen werden sollten? In meinem freigeschalteten WPF 4-Buch verwenden sie FrameworkPropertyMetadataOptions.AffectsParentArrange, das scheint jedoch in WinRT nicht verfügbar zu sein.
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
}
Changed Rückruf InvalidateArrange(), InvalidateMeasure() und UpdateLayout(), aber weder Stützpunkte in ArrangeOverride() noch MeasureOverride() sind getroffen in der Kontainer. – user263619
Vielleicht überprüft es, ob eine der Layouteigenschaften geändert wurde und wenn keine - hat es nicht aufgerufen. Möglicherweise müssen Sie dann einige der Layouteigenschaften ändern, aber dadurch können bestehende Bindungen aufgehoben werden. –