2010-07-16 15 views
2

我正在使用WPF應用程序我建立了模型 - 視圖 - 視圖模型架構,我想具體的視圖模型實際上是反應性的觀點(不正常使用的大小我知道MVVM方法的例子)。綁定到的ScrollViewer的ViewportWidth和ViewportHeight

本質上,我有一個ScrollViewer對象,我希望viewmodel能夠觀察scrollviewer的寬度和高度,然後根據寬度和高度來做相應的事情。

我想要做這樣的事情:

<ScrollViewer ViewportWidth="{Binding Path=MyViewportWidth, Mode=OneWayToSource}" ViewportHeight="{Binding Path=MyViewportHeight, Mode=OneWayToSource}" /> 

但是,當然,這是不可能做到的,因爲「ViewportWidth」和「ViewportHeight」不能被「綁定到」(又名作爲約束性指標)因爲它們是隻讀的依賴屬性(即使我沒有在這個綁定中寫入它們,因爲它是OneWayToSource)。

任何人都知道一個好的方法,以便能夠做這樣的事?

回答

1

你可以嘗試運行的是裝載的或OnResizeChanged用於更新視圖模型

private void ScrollViewer_Loaded(object sender, RoutedEventArgs e) 
{ 
    ScrollViewer sv = sender as ScrollViewer; 
    ViewModel vm = sv.DataContext as ViewModel; 

    vm.ScrollViewerHeight = sv.ViewportHeight; 
    vm.ScrollViewerWidth = sv.ViewportWidth; 
} 
1

好吧,這是一個真正的問題,但我想我會分享給後人,因爲我已經解決了這個一個我自己。我找到的最佳解決方案是創建一個從ScrollView類派生並實現所需屬性的用戶控件 - 當然,這些控件與基類的非可綁定屬性相關聯。

可以使用OnPropertyChanged功能監視這些屬性並保持值保持同步。

這裏是我的自定義用戶控件的完整代碼隱藏叫DynamicScrollViewer。請注意,我有四個名爲DynamicHorizo​​ntalOffset,DynamicVerticalOffset,DynamicViewportWidth和DynamicViewportHeight的可綁定依賴項屬性。

兩個偏移性允許的偏移的同時讀取和寫入控制,而視口特性基本上只讀的。

創建一個複雜的動畫編輯器控件時,我不得不使用這個類,其中各種組件(左側的標籤,中間的節點,頂部的時間線)需要同步滾動,但僅限於有限的方面,並且都是綁定到共同的外部滾動條。想想在電子表格中鎖定一部分行,你就會明白。

using System.Windows; 
using System.Windows.Controls; 

namespace CustomControls 
{ 
    public partial class DynamicScrollViewer : ScrollViewer 
    { 
     public DynamicScrollViewer() 
     { 
      InitializeComponent(); 
     } 

     public double DynamicHorizontalOffset 
     { 
      get { return (double)GetValue(DynamicHorizontalOffsetProperty); } 
      set { SetValue(DynamicHorizontalOffsetProperty, value); } 
     } 

     public static readonly DependencyProperty DynamicHorizontalOffsetProperty = 
      DependencyProperty.Register("DynamicHorizontalOffset", typeof(double), typeof(DynamicScrollViewer)); 

     public double DynamicVerticalOffset 
     { 
      get { return (double)GetValue(DynamicVerticalOffsetProperty); } 
      set { SetValue(DynamicVerticalOffsetProperty, value); } 
     } 

     public static readonly DependencyProperty DynamicVerticalOffsetProperty = 
      DependencyProperty.Register("DynamicVerticalOffset", typeof(double), typeof(DynamicScrollViewer)); 

     public double DynamicViewportWidth 
     { 
      get { return (double)GetValue(DynamicViewportWidthProperty); } 
      set { SetValue(DynamicViewportWidthProperty, value); } 
     } 

     public static readonly DependencyProperty DynamicViewportWidthProperty = 
      DependencyProperty.Register("DynamicViewportWidth", typeof(double), typeof(DynamicScrollViewer)); 

     public double DynamicViewportHeight 
     { 
      get { return (double)GetValue(DynamicViewportHeightProperty); } 
      set { SetValue(DynamicViewportHeightProperty, value); } 
     } 

     public static readonly DependencyProperty DynamicViewportHeightProperty = 
      DependencyProperty.Register("DynamicViewportHeight", typeof(double), typeof(DynamicScrollViewer)); 

     protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) 
     { 
      base.OnPropertyChanged(e); 
      if (e.Property == DynamicVerticalOffsetProperty) 
      { 
       if (ScrollInfo != null) 
        ScrollInfo.SetVerticalOffset(DynamicVerticalOffset); 
      } 
      else if (e.Property == DynamicHorizontalOffsetProperty) 
      { 
       if (ScrollInfo != null) 
        ScrollInfo.SetHorizontalOffset(DynamicHorizontalOffset); 
      } 
      else if (e.Property == HorizontalOffsetProperty) 
      { 
       DynamicHorizontalOffset = (double)e.NewValue; 
      } 
      else if (e.Property == VerticalOffsetProperty) 
      { 
       DynamicVerticalOffset = (double)e.NewValue; 
      } 
      else if (e.Property == ViewportWidthProperty) 
      { 
       DynamicViewportWidth = (double)e.NewValue; 
      } 
      else if (e.Property == ViewportHeightProperty) 
      { 
       DynamicViewportHeight = (double)e.NewValue; 
      } 
     } 
    } 
}