हां, मैंने अतीत में गुणों 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);
}
}