ScrollViewer中的Silverlight画布大小
本文关键字:布大小 Silverlight 中的 ScrollViewer | 更新日期: 2023-09-27 18:14:19
我正在用c#制作一个Silverlight 4网站。在其中一页,我想把两页放在一起。左边是一个地图控件,右边是一个图像。这很容易,但我也希望能够点击图像并留下PushPin像对象(如地图),所以我把图像放在画布上,只是画圆圈。问题是图像可能相当大,我需要能够滚动图像。我尝试了几种不同的方法来实现这个目标,但到目前为止都没有成功。
下面的帖子的答案似乎是要走的路,但一定有Silverlight的更新打破了它:WPF:如何使画布自动调整大小?
一个类似的解决方案建议从头开始制作画布,但我遇到了同样的问题。
我的大多数尝试都是在屏幕上显示尽可能多的图像,但是没有滚动条(仍然是灰色的)或者当图像加载时页面只是变白。
下面是我当前如何选择要加载的图像:
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;
}
可能有更好的解决方案,但这应该可以解决问题。
我已经创建了一个固定大小的ScrollViewer,它包含一个Canvas和一个图像。然后,我使用一个行为来修改画布的大小,以匹配图像的大小。该行为还处理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>
确保将i声明为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:
中对image Source属性进行数据绑定BitmapImage bi = new BitmapImage();
bi.UriSource = new Uri("http://farm7.static.flickr.com/6149/5942401995_a5a3fd3919_z.jpg");
TheImage.Source = bi;
我所需要做的就是将画布的宽度和高度设置为BitmapImage实例的PixelWidth和PixelHeight。
这就是Paul在他的解决方案中所做的(以一种更复杂的方式),但是由于某种原因,当图像在本地加载时,resize事件处理程序不会被调用。
我尝试了几种不同的建议解决方案,但我从来没有得到我想要的结果。这似乎是唯一可行的解决方案。