SORU
5 Temmuz 2009, Pazar


İterek salt okunur özellikleri ViewModel geri GUI

Her zaman görünümde salt okunur bağımlılık bazı özellikler mevcut durumu bilen bir ViewModel yazmak istiyorum.

Özellikle, benim bir GUI FlowDocument bir kerede bir sayfa gösteren bir FlowDocumentPageViewer içerir. İki gösterir FlowDocumentPageViewer salt okunur bağımlılık özellikleri CanGoToPreviousPage ve CanGoToNextPage aradı. Benim ViewModel her zaman bu iki Görünüm özelliklerinin değerlerini öğrenmek istiyorum.

OneWayToSource bir veri bağlama ile bunu yapabileceğimi düşündüm:

<FlowDocumentPageViewer
    CanGoToNextPage="{Binding NextPageAvailable, Mode=OneWayToSource}" ...>

Eğer bu yasak olsaydı, mükemmel olurdu: FlowDocumentPageViewer. CanGoToNextPage özelliği değişti zaman, yeni bir değer istiyorum tam olarak ViewModel. NextPageAvailable özelliği, içine aşağı itti.

Ne yazık ki, bu derleme değildir: bir hata diyorum'CanGoToPreviousPage' özelliği salt okunur ve hiçbir şekilde biçimlendirme. itibarenGörünüşe göre özellikleri desteği yokherhangi birbiraz veri bile veri salt okunur özellik bakımından.

Ben gelebilirim benim ViewModel özellikleri olması DependencyProperties, ve bir tek yönlü bağlama diğer yoldan gitmeye, ama ben sevmiyorum ayrılık-endişeleri ihlali (ViewModel ne yapmalıyım? başvuru için Görünüm, MVVM veri bağlama için gerekiyor kaçının).

FlowDocumentPageViewer değil ortaya bir CanGoToNextPageChanged olay, bilmiyorum, herhangi bir iyi bir yol için değişiklik bildirimleri bir DependencyProperty, kısa oluşturma başka bir DependencyProperty bağlamak için, hangi abartılı gibi görünüyor burada.

Nasıl benim ViewModel manzara salt-okunur özellikler değişiklik haberdar olabilirim?

CEVAP
5 Temmuz 2009, Pazar


Evet, salt okunur hem de ActualWidth ActualHeight özellikleri, geçmişte böyle bir şey yapmadım. ObservedWidth ObservedHeight özellikler bağlı olan ekli bir davranış oluşturdu. Ayrıca başlangıç yapmak için kanca-up kullanılan Observe bir özelliği vardır. Kullanımı bu gibi görünüyor:

<UserControl ...
    SizeObserver.Observe="True"
    SizeObserver.ObservedWidth="{Binding Width, Mode=OneWayToSource}"
    SizeObserver.ObservedHeight="{Binding Height, Mode=OneWayToSource}"

Görünüm model Width Height her zaman uyumlu özellikleri ObservedWidth ObservedHeight bağlı özellikleri vardır. Observe Bu özellik sadece FrameworkElement SizeChanged olay bağlanır. Kolu, ObservedWidth ObservedHeight özelliklerini günceller. Ergo, görünüm modeli Width Height her zaman UserControl ActualWidth ActualHeight ile eşitlendi.

Belki mükemmel bir çözüm (katılıyorum - salt okunur DPs değilgerekirOneWayToSource veri bağlantıları) destek, ama çalışıyor ve MVVM desen bunu onadı. Belli ki, ObservedWidth ObservedHeight DPsdeğilsalt okunur.

GÜNCELLEME: uygulayan işte işlevselliğini yukarıda açıklanan kod:

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);
    }
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • 3DS Max Tutorials

    3DS Max Tuto

    4 AĞUSTOS 2013
  • Andytokkallos

    Andytokkallo

    27 Kasım 2007
  • FamilyFeud

    FamilyFeud

    22 AĞUSTOS 2006