2

構築しているWPFアプリケーションでModel-View-ViewModelアーキテクチャを使用していますが、特定のViewModelを実際にビューのサイズに反応させたいと考えています(MVVMアプローチの通常のユースケースではありません)。 。

基本的に、私はScrollViewerオブジェクトを持っており、viewmodelがscrollviewerの幅と高さを監視し、その幅と高さに応じて処理できるようにする必要があります。

私はこのようなことをしたいです:

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

ただし、もちろん、「ViewportWidth」と「ViewportHeight」は読み取り専用の依存関係プロパティであるため(これではまったく書き込みを行っていませんが)、「バインド」(バインドターゲットとして機能)できないため、これを行うことはできません。 OneWayToSourceであるため、バインディング)。

誰かがこのようなことをすることができる良い方法を知っていますか?

4

2 に答える 2

1

ビューモデルを更新するOnLoadedまたは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;
}
于 2010-07-16T17:03:14.323 に答える
1

さて、これは本当に古い質問ですが、私はこれを自分で解決したので、後世のために共有したいと思いました。私が見つけた最善の解決策は、ScrollViewクラスから派生し、必要なプロパティを実装するユーザーコントロールを作成することです。もちろん、これらは基本クラスのバインド不可能なプロパティにリンクされています。

OnPropertyChanged関数を使用して、これらのプロパティを監視し、値の同期を維持できます。

これが、DynamicScrollViewerと呼ばれるカスタムユーザーコントロールの完全なコードビハインドです。DynamicHorizo​​ntalOffset、DynamicVerticalOffset、DynamicViewportWidth、およびDynamicViewportHeightという4つのバインド可能な依存関係プロパティがあることに注意してください。

2つのオフセットプロパティを使用すると、オフセットの読み取りと書き込みの両方を制御できますが、ビューポートプロパティは基本的に読み取り専用です。

さまざまなコンポーネント(左側のラベル、中央のノード、上部のタイムライン)が同期的にスクロールする必要がある複雑なアニメーションエディタコントロールを作成するときにこのクラスを使用する必要がありましたが、限られた側面でのみ、すべて共通の外部にバインドされていましたスクロールバー。スプレッドシートの行のセクションをロックすることを考えてみてください。そうすれば、そのアイデアが得られます。

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;
            }
        }
    }
}
于 2015-12-08T21:29:32.127 に答える