हां, मैंने अतीत में गुणों ActualWidth
और ActualHeight
गुणों के साथ ऐसा किया है , जो दोनों केवल-पढ़ने के लिए हैं। मैंने एक संलग्न व्यवहार बनाया है जिसमें गुण हैं ObservedWidth
और ObservedHeight
संलग्न हैं। इसमें एक Observe
संपत्ति भी है जिसका उपयोग प्रारंभिक हुक-अप करने के लिए किया जाता है। उपयोग इस तरह दिखता है:
<UserControl ...
SizeObserver.Observe="True"
SizeObserver.ObservedWidth="{Binding Width, Mode=OneWayToSource}"
SizeObserver.ObservedHeight="{Binding Height, Mode=OneWayToSource}"
तो दृश्य मॉडल में Width
और Height
गुण होते हैं जो हमेशा ObservedWidth
और ObservedHeight
संलग्न गुणों के साथ होते हैं। Observe
संपत्ति बस से जुड़ SizeChanged
जाने की स्थिति FrameworkElement
। हैंडल में, यह इसके ObservedWidth
और ObservedHeight
गुणों को अपडेट करता है । एर्गो, Width
और Height
दृश्य मॉडल हमेशा ActualWidth
और ActualHeight
के साथ सिंक में होता है UserControl
।
शायद सही समाधान नहीं है (मैं सहमत हूं - केवल पढ़ने के लिए डीपी कोOneWayToSource
बाइंडिंग का समर्थन करना चाहिए ), लेकिन यह काम करता है और यह एमवीवीएस पैटर्न को बढ़ाता है। जाहिर है, ObservedWidth
और ObservedHeight
डीपी केवल-पढ़ने के लिए नहीं हैं।
अद्यतन: यहाँ कोड है कि ऊपर वर्णित कार्यक्षमता को लागू करता है:
public static class SizeObserver
{
public static readonly DependencyProperty ObserveProperty = DependencyProperty.RegisterAttached(
"Observe",
typeof(bool),
typeof(SizeObserver),
new FrameworkPropertyMetadata(OnObserveChanged));
public static readonly DependencyProperty ObservedWidthProperty = DependencyProperty.RegisterAttached(
"ObservedWidth",
typeof(double),
typeof(SizeObserver));
public static readonly DependencyProperty ObservedHeightProperty = DependencyProperty.RegisterAttached(
"ObservedHeight",
typeof(double),
typeof(SizeObserver));
public static bool GetObserve(FrameworkElement frameworkElement)
{
frameworkElement.AssertNotNull("frameworkElement");
return (bool)frameworkElement.GetValue(ObserveProperty);
}
public static void SetObserve(FrameworkElement frameworkElement, bool observe)
{
frameworkElement.AssertNotNull("frameworkElement");
frameworkElement.SetValue(ObserveProperty, observe);
}
public static double GetObservedWidth(FrameworkElement frameworkElement)
{
frameworkElement.AssertNotNull("frameworkElement");
return (double)frameworkElement.GetValue(ObservedWidthProperty);
}
public static void SetObservedWidth(FrameworkElement frameworkElement, double observedWidth)
{
frameworkElement.AssertNotNull("frameworkElement");
frameworkElement.SetValue(ObservedWidthProperty, observedWidth);
}
public static double GetObservedHeight(FrameworkElement frameworkElement)
{
frameworkElement.AssertNotNull("frameworkElement");
return (double)frameworkElement.GetValue(ObservedHeightProperty);
}
public static void SetObservedHeight(FrameworkElement frameworkElement, double observedHeight)
{
frameworkElement.AssertNotNull("frameworkElement");
frameworkElement.SetValue(ObservedHeightProperty, observedHeight);
}
private static void OnObserveChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var frameworkElement = (FrameworkElement)dependencyObject;
if ((bool)e.NewValue)
{
frameworkElement.SizeChanged += OnFrameworkElementSizeChanged;
UpdateObservedSizesForFrameworkElement(frameworkElement);
}
else
{
frameworkElement.SizeChanged -= OnFrameworkElementSizeChanged;
}
}
private static void OnFrameworkElementSizeChanged(object sender, SizeChangedEventArgs e)
{
UpdateObservedSizesForFrameworkElement((FrameworkElement)sender);
}
private static void UpdateObservedSizesForFrameworkElement(FrameworkElement frameworkElement)
{
// WPF 4.0 onwards
frameworkElement.SetCurrentValue(ObservedWidthProperty, frameworkElement.ActualWidth);
frameworkElement.SetCurrentValue(ObservedHeightProperty, frameworkElement.ActualHeight);
// WPF 3.5 and prior
////SetObservedWidth(frameworkElement, frameworkElement.ActualWidth);
////SetObservedHeight(frameworkElement, frameworkElement.ActualHeight);
}
}