2011-11-14 38 views
0

我正在用C#制作一个Silverlight 4网站。在其中一页中,我想要有两个旁边的面板。左边是地图控件,右边是图片。这很容易,但我也希望能够点击图像并保持PushPin像对象(如地图),所以我把图像放在画布上,然后画圆圈。问题是图像可能相当大,我需要能够滚动图像。我尝试了几种不同的方法来实现这一点,但迄今为止没有运气。ScrollViewer中的Silverlight Canvas大小调整

下面的文章的答案似乎是要走的路,但必须有更新破坏它的Silverlight。 WPF: How to make canvas auto-resize?

一个类似的解决方案建议从头开始制作画布,但我遇到了同样的问题。 http://themechanicalbride.blogspot.com/2008/11/auto-sizing-canvas-for-silverlight-and.html

我的大多数尝试都是尽可能地在屏幕上显示尽可能多的图像,但没有滚动条(仍然呈灰色),或者当图像加载时页面变白。

如果需要,我可以提供代码,请让我知道。 任何帮助将不胜感激。

下面是我当前如何选择图像加载:

 OpenFileDialog dialog = new OpenFileDialog(); 
     dialog.Filter = "Image Files (*.png, *.jpg)|*.jpg;*.png"; 
     if(dialog.ShowDialog() == true) { 
      BitmapImage bitmap = new BitmapImage(); 
      FileStream stream = dialog.File.OpenRead(); 
      bitmap.SetSource(stream); 
      TheImage.Source = bitmap; 
     } 

回答

0

原来,最起码,我需要做的是设置宽度并将画布的高度设置为BitmapImage实例的PixelWidth和PixelHeight。

这就是Paul用他的解决方案(以一种更复杂一点的方式)所做的,但由于某种原因,resize事件处理程序在本地加载图像时不会被调用。

我曾尝试过几种不同的建议解决方案,但我从来没有得到我想要的结果。这是似乎工作的唯一解决方案。

1

则有可能是一个更好的解决办法,但是这应该做的伎俩。

我创建了一个包含画布和图像的小型固定大小ScrollViewer。然后我使用了一种行为来修改画布的大小以匹配图像的大小。该行为还会处理ImageOpened事件,以在图像打开后设置图像的正确大小。

这里是XAML:

<ScrollViewer Width="200" Height="200" HorizontalScrollBarVisibility="Auto"> 
    <Canvas x:Name="TheCanvas"> 
     <Image x:Name="TheImage"> 
      <i:Interaction.Behaviors> 
       <Views:ResizeCanvasBehaviour Canvas="{Binding ElementName=TheCanvas}"/> 
      </i:Interaction.Behaviors> 
     </Image> 
    </Canvas> 
</ScrollViewer> 

一定要声明我为xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 和b放在什么地方的行为的命名空间相匹配。

这里是行为的代码:

public class ResizeCanvasBehaviour : Behavior<Image> 
{ 
    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     AssociatedObject.SizeChanged += AssociatedObject_SizeChanged; 
     AssociatedObject.ImageOpened += AssociatedObject_ImageOpened; 
    } 

    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 
     AssociatedObject.SizeChanged -= AssociatedObject_SizeChanged; 
     AssociatedObject.ImageOpened -= AssociatedObject_ImageOpened; 
    } 

    private void AssociatedObject_ImageOpened(object sender, RoutedEventArgs e) 
    { 
     BitmapSource bitmapSource = AssociatedObject.Source as BitmapSource; 
     if (bitmapSource == null) 
     { 
      return; 
     } 

     AssociatedObject.Width = bitmapSource.PixelWidth; 
     AssociatedObject.Height = bitmapSource.PixelHeight; 

     Resize(); 
    } 

    private void AssociatedObject_SizeChanged(object sender, SizeChangedEventArgs e) 
    { 
     Resize(); 
    } 

    public Canvas Canvas 
    { 
     get { return GetValue(CanvasProperty) as Canvas; } 
     set { SetValue(CanvasProperty, value); } 
    } 

    public static readonly DependencyProperty CanvasProperty = DependencyProperty.Register(
     "Canvas", 
     typeof(Canvas), 
     typeof(ResizeCanvasBehaviour), 
     new PropertyMetadata(null, CanvasPropertyChanged)); 

    private static void CanvasPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     ((ResizeCanvasBehaviour)d).OnCanvasPropertyChanged(); 
    } 

    private void OnCanvasPropertyChanged() 
    { 
     if (Canvas != null) 
     { 
      Resize(); 
     } 
    } 

    private void Resize() 
    { 
     if ((AssociatedObject != null) && (Canvas != null)) 
     { 
      Canvas.Width = AssociatedObject.ActualWidth; 
      Canvas.Height = AssociatedObject.ActualHeight; 
     } 
    } 
} 

要加载的图像做这样的事。我这样做背后的代码的运行速度,但最好你应该把这个视图中的模型,然后数据的图像源属性绑定在XAML:

BitmapImage bi = new BitmapImage(); 
bi.UriSource = new Uri("http://farm7.static.flickr.com/6149/5942401995_a5a3fd3919_z.jpg"); 
TheImage.Source = bi; 
+0

我实际上已经考虑过如何使用Behavior类,但是我并不认为它可用于制作网页,只有桌面应用程序。 [MSDN](http://msdn.microsoft.com/en-us/library/system.windows.forms.design.behavior.behavior.aspx)将其列在System.Windows.Forms下。设计,这是为WPF。由于我没有制作WPF应用程序,我该如何去使用它? –

+0

如果您尚未拥有它,则需要[Expression Blend SDK](http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=3062),然后引用System.Windows。互动。我在Silverlight应用程序中测试了它,所以它可以正常工作。如果您愿意,您可以随时在代码后面添加SizeChanged事件处理程序,但如果您使用的是MVVM,则可以采取行为 - 它是自包含的并可重用的。 –

+0

我在上面的问题中遗漏的一件事是用户加载图像,所以我不会提前知道图像的大小。如果图像小于800x600,则解决方案可以正常工作,但如果图像较大,则会剪裁图像。很显然,我可以改变尺寸,但只是改变xaml的尺寸实际上会影响结果。当我尝试在用户加载图像后更改图像的大小时,没有任何更改。 –

相关问题