2013-10-09 48 views
0

我決定用完整的代碼解決這個問題。我創建了一個測試用例來證明我認爲的怪異行爲,以便其他人可以運行代碼。WPF是scrollviewer在大值時精確的水平偏移量嗎?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Media; 

namespace Test 
{ 
    public class TestSizeVisual: FrameworkElement 
    { 

    public double MinimumXInDIPs 
    { 
     get { return (double)GetValue(MinimumXInDIPsProperty); } 
     set 
     { 
     SetValue(MinimumXInDIPsProperty, value); 
     } 
    } 
    public static readonly DependencyProperty MinimumXInDIPsProperty = 
     DependencyProperty.Register("MinimumXInDIPs", 
     typeof(double), typeof(TestSizeVisual), 
     new FrameworkPropertyMetadata(new double(), new PropertyChangedCallback(Redraw))); 

    public double ViewportWidth 
    { 
     get { return (double)GetValue(ViewportWidthProperty); } 
     set 
     { 
     SetValue(ViewportWidthProperty, value); 
     } 
    } 
    public static readonly DependencyProperty ViewportWidthProperty = 
     DependencyProperty.Register("ViewportWidth", 
     typeof(double), typeof(TestSizeVisual), 
     new FrameworkPropertyMetadata(new double(), FrameworkPropertyMetadataOptions.AffectsMeasure)); 



    VisualCollection visuals; 

    protected override Size MeasureOverride(Size availableSize) 
    { 
     return new Size(50000000000, 50); 
    } 

    public TestSizeVisual() 
    { 
     visuals = new VisualCollection(this); 
     this.Loaded += new RoutedEventHandler(TestSizeVisual_Loaded); 
    } 

    void TestSizeVisual_Loaded(object sender, RoutedEventArgs e) 
    { 
     DrawSignal(); 
    } 
    private static void Redraw(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     TestSizeVisual sg = d as TestSizeVisual; 
     if (sg != null && sg.IsLoaded) 
     { 
     sg.DrawSignal(); 
     } 
    } 


    private void DrawSignal() 
    { 
     DrawingVisual signalbox = new DrawingVisual(); 
     using (DrawingContext dc = signalbox.RenderOpen()) 
     { 
     dc.DrawRectangle(Brushes.Orange, new Pen(Brushes.Black, 2), new Rect(new Point(0, 0), new Point(1000000000, ActualHeight))); 
     dc.DrawRectangle(Brushes.Purple, new Pen(Brushes.Black, 2), new Rect(new Point(MinimumXInDIPs, 2), new Point(MinimumXInDIPs + 10, 6))); 
     dc.DrawRectangle(Brushes.Purple, new Pen(Brushes.Black, 2), new Rect(new Point(MinimumXInDIPs + ViewportWidth - 10, 2), new Point(MinimumXInDIPs + ViewportWidth, 6))); 
     dc.DrawLine(new Pen(Brushes.Black, 2), new Point(MinimumXInDIPs, 10), 
         new Point(MinimumXInDIPs + ViewportWidth, 10)); 
     } 
     visuals.Add(signalbox); 
     InvalidateVisual(); 


    } 


    protected override Visual GetVisualChild(int index) 
    { 
     return visuals[index]; 
    } 
    protected override int VisualChildrenCount 
    { 
     get 
     { 
     return visuals.Count; 
     } 
    } 

    } 
} 

XAML文件看起來是這樣的:

<ScrollViewer 
    x:Name="scrollviewer1" 
    HorizontalAlignment="Stretch"  
    VerticalAlignment="Stretch" 
    HorizontalContentAlignment="Left" 
    HorizontalScrollBarVisibility="Visible" 
    VerticalScrollBarVisibility="Visible" 
    > 
    <test:TestSizeVisual 
     MinimumXInDIPs="{Binding ElementName=scrollviewer1, Path=HorizontalOffset}" 
     ViewportWidth="{Binding ElementName=scrollviewer1, Path=ViewportWidth}" 
     /> 
    </ScrollViewer> 

的矩形和線保持集中在屏幕上滾動的testsizevisual的小尺寸。但是,一旦我改變measureoverride返回一個巨大的大小,滾動不再導致正確的圖紙居中。爲什麼一切都會出現巨大的尺寸?我是否需要編寫自己的scrollviewer才能容納更多的內容,或者是否有解決方法?

回答

1

所以有個朋友終於明白了我的意思。儘管我正在做雙打計算,但WPF使用直接x進行繪圖。 Direct x受限於浮點數。通過檢查wiki上浮點數的尾數,我發現我已經超過浮點數的尾數值,因此這個值不再準確。