bugfix> wpf > 投稿

WPFコントロール(またはウィンドウ)に特定のアスペクト比を維持するように指示できる方法を探していました。

  1. Window の場合見つけたこの ソリューション、それは非常にうまく機能します。ただし、Win32 APIとウィンドウハンドルを使用するため、WPF Control に対して機能しません。 s(WPFで知っている限りでは、ウィンドウ自体にのみハンドルがあるため)
  2. Control の場合1つは通常、 Control を置くためのアドバイスを受けますで ViewBox 、しかし、コントロールを拡大縮小したくないので、サイズを変更します(そして、境界線の幅やフォントサイズを維持します)。
  3. Control のその他の「ソリューション」 Width をバインドする任意の形式を含む ActualHeight へまたは Height ActualWidth へ 、または SizeChanged を使用しかし、これはサイズ変更中に大きなちらつきをもたらし、あまり信頼性がありません。 Width をバインドする場合 ActualHeightWidth のみをサイズ変更することはできません(右の境界線をドラッグすることにより) ActualHeight 変わらない。 イベントの場合、幅と高さが同時に変化するとトリッキーになります。その後、 SizeChanged 内のサイズを変更する必要があります。イベント...と私はちらつきに言及しましたか?

多くの読書と検索の後、特定のアスペクト比を維持するようにコントロールを強制する最良の方法は、 Measure 内でそれを行うことであるという結論に達しましたおよび Arrange 関数。

見つけたこの  Decorator を作成するソリューションオーバーライドされた Measure による制御および Measure 機能しますが、それはそれ自身の Decorator 内にアスペクト比を維持することになっているコントロールを置くことを意味します 。必要に応じてそれと一緒に暮らすこともできますが、もっと良い方法はないかと思います。

だから、ここに私の質問があります。添付プロパティ Ratio を作成することは可能ですかおよび添付プロパティ KeepRatio そしてどういうわけか Measure をオーバーライドしますおよび Arrange OnKeepRatioChanged 内の問題のコントロールの機能および RatioChanged 添付プロパティのコールバック?

回答 1 件
  • Arrange/Measureメソッドをオーバーライドする場合、添付プロパティは必要ありません。このラッパーは問題ないはずです:

    public partial class RatioKeeper : UserControl
    {
        public static readonly DependencyProperty VerticalAspectProperty = DependencyProperty.Register(
            "VerticalAspect", typeof(double), typeof(RatioKeeper), new PropertyMetadata(1d));
        public static readonly DependencyProperty HorizontalAspectProperty = DependencyProperty.Register(
            "HorizontalAspect", typeof(double), typeof(RatioKeeper), new PropertyMetadata(1d));
        public double HorizontalAspect
        {
            get { return (double) GetValue(HorizontalAspectProperty); }
            set { SetValue(HorizontalAspectProperty, value); }
        }
        public double VerticalAspect
        {
            get { return (double) GetValue(VerticalAspectProperty); }
            set { SetValue(VerticalAspectProperty, value); }
        }
        public RatioKeeper()
        {
            InitializeComponent();
        }
        //arrangeBounds provides size of a host.
        protected override Size ArrangeOverride(Size arrangeBounds)
        {
            //Calculation of a content size that wont exceed host's size and will be of the desired ratio at the same time
            var horizontalPart = arrangeBounds.Width / HorizontalAspect;
            var verticalPart = arrangeBounds.Height / VerticalAspect;
            var minPart = Math.Min(horizontalPart, verticalPart);
            var size = new Size(minPart * HorizontalAspect, minPart * VerticalAspect);
            //apply size to wrapped content
            base.ArrangeOverride(size);
            //return size to host
            return size;
        }
    }
    
    

あなたの答え