【问题标题】:Assign Image instead of Stream to Windows::UI::Xaml::Controls::Image将图像而不是流分配给 Windows::UI::Xaml::Controls::Image
【发布时间】:2013-05-09 00:05:55
【问题描述】:

我创建了一个UserControl,其中包含一个Grid,其中包含一个Image-控件。

<UserControl
    x:Class="Album.AlbumPicture"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Album"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400"
    Width="200"
    Height="200"
    >

    <Grid Width="200" Height="200">
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Image Name="AlbumPictureImage" Width="200" Height="200" Grid.Column="0" Grid.Row="0"  />
    </Grid>
</UserControl>

现在,我有一个构造函数,它采用现有的Image(从Stream 新创建)并将Image 分配给我的自定义控件的Image

AlbumPicture::AlbumPicture(Windows::UI::Xaml::Controls::Image^ Image){
InitializeComponent();
this->AlbumPictureImage = Image;
this->Height = 200;
this->Width = 200;
this->state = AlbumPictureState::SWIPE;
this->StartingPoint = Point(0,0);
} 

为了确保我的UserControl 被附加到布局容器中,我将GridBackground 设置为白色,它显示得很好。我还将Image 直接添加到布局容器中,并且显示正确。


现在,当我将构造函数更改为

AlbumPicture::AlbumPicture(Windows::UI::Xaml::Media::ImageSource^ Source){
InitializeComponent();
this->AlbumPictureImage->Source = Source;
this->Height = 200;
this->Width = 200;
this->state = AlbumPictureState::SWIPE;
this->StartingPoint = Point(0,0);
}

一切正常,Image 将显示出来。这里有什么问题?

【问题讨论】:

  • 原谅我的提问,但你问的是什么问题?
  • @JerryNixon-MSFT using .NET/C# 我习惯于相对简单的分配,我也缺乏 WPF 知识。我预计,如果我简单地将Image-control-reference 分配给我的UserControlImage,它将正确显示,但如果我使用我的第一种方法,则没有任何显示。我只是不明白为什么它不显示...
  • 使用 C# 吧?在我看来更像 C++/CX。话虽如此,您是否要将新图像添加到 Container.Children 集合中,以便将其包含在 XAML 可视化树中?
  • 标记正确/最佳答案是有礼貌的。
  • 对不起,我以为我做到了......

标签: user-controls windows-runtime winrt-xaml c++-cx


【解决方案1】:

所以我实际上是 C#/Xaml 开发人员,但我认为原因是您将控件的引用设置为新图像,但根本没有更新可视树。您可能只是更改了“this.AlbumPictureImage”对象的引用,而可视化树(即带有父/子引用的 FrameworkElement)保留了旧引用。

当您在第二个示例中将实际图像加载到引用的 Image 对象中时,您根本不会更改(或尝试更改)可视化树,因此会显示控件。

在我看来,如果我是对的,你有两个选择:

  • 更改视觉树本身。在 Image Control 的父级中删除对子级的引用,然后添加新的图像控件。

  • 将树中旧图像控件的图像源设置为树中新图像的图像源。

第一个要困难得多,而且充满危险,尤其是如果其中任何一个是异步的。我很确定 Image 控件知道使用调度程序来设置其图像源,因此应该在此处介绍第二个选项。你肯定不会得到第一个保护,所以你需要确保编组到 UI 线程(使用调度程序),以防异步线程没有 UI 访问权限。

第二个选项也应该很容易实现。如果这段代码很糟糕或被破坏,我绝对道歉,正如我所说的:

AlbumPicture::AlbumPicture(Windows::UI::Xaml::Controls::Image^ Image){
InitializeComponent();
this->AlbumPictureImage->Source = Image::Source
this->Height = 200;
this->Width = 200;
this->state = AlbumPictureState::SWIPE;
this->StartingPoint = Point(0,0);
} 

我不知道两个控件的源是否相同,因此您可能需要以某种方式分离它,或者获取底层流并从流本身创建一个新的 ImageSource 对象。

编码不错!

【讨论】:

  • +1 感谢您的回复。我实际上在代码中尝试了您的第二个建议。它有效,但看起来很笨拙(不是这是你的错或任何事情!!!)
  • 是的,我认为他们更喜欢您传递数据而不是控件本身,例如在您的第二个示例中。我知道这并不总是可能的,但如果可以的话,这样做可能更安全。
  • 嗯,这适用于我使用 .NET/C# 的工作,在我看来,它比 WinRT 更“对开发人员友好”,至少对于该领域的初学者而言。
【解决方案2】:

好吧,让我们假设你有一个这样的usercontrol

<UserControl Loaded="UserControl_Loaded_1">
    <Grid>
        <Image x:Name="MyImage" />
    </Grid>
</UserControl>

如您所见,我将使用loaded 事件而不是用户控件的constructor。但它应该导致相同的实现。

loaded 事件中,我想采用stream(在这种情况下,我将使用BitmapImage 类型)并将其设置为现有图像,如您在上面的问题中所述:

private void UserControl_Loaded_1(object sender, RoutedEventArgs e)
{
    var _Url = new Uri("ms-appx:///assets/logo.png");
    var _Image = new Image
    {
        Source = new BitmapImage(_Url)
    };
    this.MyImage.Source = _Image.Source;
}

是的,那是 C#,而不是 C++/CX。但我认为这是有道理的。

然后,我将usercontrol 的图像source 属性的源设置为现有image 控件的source 属性。这是一个简单的属性分配。这工作正常。可以丢弃以前存在的image 控件。 usercontrol 中的 image 将为您显示以前的 image 控件的图像。

我强烈建议您查看image 控件的CacheMode 属性,因为如果您不明白它在做什么,它可能会让您陷入循环。以下是 meta cmets 所说的:

//     A value that indicates that rendered content should be cached when possible.
//     If you specify a value of CacheMode, rendering operations from RenderTransform
//     and Opacity execute on the graphics processing unit (GPU), if available.
//     The default is null, which does not enable a cached composition mode.

祝你好运。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    • 1970-01-01
    • 2019-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多