WPF - 图像控制实际大小

发布于 2024-09-09 10:08:34 字数 244 浏览 5 评论 0原文

我在 WPF 中获取图像控件的 ActualHeightActualWidth 时遇到问题。当用户选择图像文件时,我想根据图像控件的尺寸调整所选图像的大小。

我试图在窗口初始化时获取Image.ActualHeightImage.ActualWidth,但我发现Image控件的两个属性都是“0”。

那么如何获取图像控件的尺寸呢。

I have a problem in getting ActualHeight and ActualWidth of image control in WPF. When user selects the image file, I want to resize the selected image based on the dimensions of the image control.

I tried to get the Image.ActualHeight and Image.ActualWidth when window initializes, but I found that both properties of Image control are '0'.

So how to get the dimensions of the image control.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

悸初 2024-09-16 10:08:34

FrameworkElement.ActualHeight 的评论说房产发挥其真正价值之前可能会有一些滞后。

该属性是计算值
基于其他高度输入,以及
布局系统。该值由以下设置
布局系统本身,基于
实际渲染过程,并且可能
因此稍微落后于集合
属性值,例如高度
这是输入的基础
改变。

控件的最终大小由 FrameworkElement.Arrange 设置(-覆盖)。您可以重写该方法并仅调用基类实现。它的返回值将是图像的实际大小。

the remarks for FrameworkElement.ActualHeight say that there might be some lag before the property has its real value.

This property is a calculated value
based on other height inputs, and the
layout system. The value is set by the
layout system itself, based on an
actual rendering pass, and may
therefore lag slightly behind the set
value of properties such as Height
that are the basis of the input
change.

The final size of your control is set by FrameworkElement.Arrange(-Override). You could override the method and just call the base class implementation. Its return value will be the actual size of your Image.

浅忆流年 2024-09-16 10:08:34

在我的脑海中,我认为您应该订阅图像控件上的 Load 事件,在该事件触发之前,ActualHeight/Width 不会更新。

Off the top of my head, I think you should subscribe to the Load event on the image control, the ActualHeight/Width are not updated until that event fires.

ζ澈沫 2024-09-16 10:08:34

控件的 ActualSize 在“Measure”布局过程之后设置(“Arrange”布局过程设置其位置)。另外两个答案很有帮助;容器的“排列”布局过程仅在测量其子级之后发生,并且图像控件的加载处理程序应在其第一个布局过程完成后调用。

The control's ActualSize is set after the "Measure" layout pass (the "Arrange" layout pass sets its location). The other two answers are helpful; the "Arrange" layout pass of the container only happens after its children have been measured, and the load handler of your image control should be called after its first layout pass has completed.

日暮斜阳 2024-09-16 10:08:34

我发现的最佳解决方案是等到图像加载后。

Private Sub Update_imgImage(tURI As Uri)
    imgImage.LayoutTransform = New ScaleTransform(scaleX:=1, scaleY:=1)
    Dim src As BitmapImage = New BitmapImage()
    src.BeginInit()
    src.UriSource = tURI
    src.CacheOption = BitmapCacheOption.OnLoad
    src.EndInit()
    imgImage.SetCurrentValue(Image.SourceProperty, src)
    AddHandler src.DownloadCompleted, AddressOf ImageDownloadCompleted
End Sub

然后对于 ImageDownloadCompleted 我有以下内容:

Sub ImageDownloadCompleted(sender As Object, e As System.EventArgs)
    Dim src As BitmapImage
    src = DirectCast(sender, BitmapImage)
    Dim scaleXY As Double
    If sender.Width = 0 Then Exit Sub
    'default width is 600 for my item, if changed, then resize
    If sender.Width <> 600 Then
        scaleXY = 500 / sender.Width
        imgImage.LayoutTransform = New ScaleTransform(scaleX:=scaleXY, scaleY:=scaleXY)
    Else
        imgImage.LayoutTransform = New ScaleTransform(scaleX:=1, scaleY:=1)
    End If
    RemoveHandler src.DownloadCompleted, AddressOf ImageDownloadCompleted
End Sub

我希望这对您有用。

The Best solution I have found is to wait until after the Image has loaded.

Private Sub Update_imgImage(tURI As Uri)
    imgImage.LayoutTransform = New ScaleTransform(scaleX:=1, scaleY:=1)
    Dim src As BitmapImage = New BitmapImage()
    src.BeginInit()
    src.UriSource = tURI
    src.CacheOption = BitmapCacheOption.OnLoad
    src.EndInit()
    imgImage.SetCurrentValue(Image.SourceProperty, src)
    AddHandler src.DownloadCompleted, AddressOf ImageDownloadCompleted
End Sub

Then for ImageDownloadCompleted i have the following:

Sub ImageDownloadCompleted(sender As Object, e As System.EventArgs)
    Dim src As BitmapImage
    src = DirectCast(sender, BitmapImage)
    Dim scaleXY As Double
    If sender.Width = 0 Then Exit Sub
    'default width is 600 for my item, if changed, then resize
    If sender.Width <> 600 Then
        scaleXY = 500 / sender.Width
        imgImage.LayoutTransform = New ScaleTransform(scaleX:=scaleXY, scaleY:=scaleXY)
    Else
        imgImage.LayoutTransform = New ScaleTransform(scaleX:=1, scaleY:=1)
    End If
    RemoveHandler src.DownloadCompleted, AddressOf ImageDownloadCompleted
End Sub

I hope this works for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文