0

我正在为 Windows Embedded 项目开发 Silverlight。我定义了一个由图像控件组成的自定义用户控件。我想在 xaml 中为自定义控件的不同实例指定不同的图像源。所以我在自定义控件中定义了一个依赖属性“MyImage”。

在 Blend C# 代码隐藏中: public UserControl1() { InitializeComponent(); ItemImage.DataContext = 这个;}

    public ImageSource MyImage
    {
        get { return (ImageSource)GetValue(MyImageProperty); }
        set { SetValue(MyImageProperty, value); }
    }

    public static readonly DependencyProperty MyImageProperty =
        DependencyProperty.Register("MyImage", typeof(ImageSource), typeof(UserControl1), null);

在 UserControl.xaml 中,我将图像控件 Source 属性绑定到 MyImage:

<Image x:Name="ItemImage" Margin="0,0,90,0" Source="{Binding MyImage}"/>

因此,当我使用自定义控件时,我可以在 xaml 中执行此操作:

<local:UserControl1 HorizontalAlignment="Left" Margin="94,117,0,0" Width="196" Height="85" VerticalAlignment="Top" MyImage="img1.png"/>
<local:UserControl1 HorizontalAlignment="Left" Margin="94,217,0,0" Width="196" Height="85" VerticalAlignment="Top" MyImage="img2.png"/>

在 Blend 中测试是可以的。我可以看到两个自定义控件实例中显示的两个图像。

然后来到 SWE C++ 代码隐藏,我在 UserControl1.cpp 中重新定义并注册了依赖属性:

XRDependencyPropertyMetaData dpmImage = XRDependencyPropertyMetaData();
dpmImage.Size = sizeof(IXRImageSource);
dpmImage.pfnPropertyChangeNotification = ImagePropertyChanged;
dpmImage.pfnTypeConverter = ConvertNameTypeConverter;
dpmImage.pfnEnumerableCreation = NULL;

XRValue defImage;
defImage.vType = VTYPE_OBJECT;
defImage.pObjectVal = NULL;
dpmImage.DefaultValue = defImage;

hr = pApplication->RegisterDependencyProperty(L"MyImage", VTYPE_OBJECT, ControlID(), &dpmImage, &m_dpMyImageID);

void UserControl1::ImagePropertyChanged( __in IXRDependencyObject* pControl, __in XRValue* pOldValue, __in XRValue* pNewValue )
{......}
HRESULT UserControl1::ConvertNameTypeConverter( XRValue *pValIn, XRValue *pValOut )
{......}

编译执行成功,只是我没有看到两个控件中显示图片。

调试时,我可以看到首先调用了 ConvertNameTypeConverter 回调。我可以看到图像文件名作为字符串存储在 pValIn 中,这与 MSDN 文档描述的内容一致:当 XAML for Windows Embedded 在解析阶段调用此函数时,pValIn 将始终是一个字符串。

接下来调用 ImagePropertyChanged 回调,我可以看到 pNewValue 包含我在 ConvertNameTypeConverter() 中设置为 pValOut 的值。

我的问题是,我的做法是否正确?如果我只能获取图像文件名的字符串,如何从字符串中获取图像二进制文件?

有没有办法将图像二进制文件从 xaml 直接传输到 C++ 代码隐藏并直接显示?

谢谢!

4

2 回答 2

0

问题解决了。但我认为我的解决方案看起来只是一种解决方法。在回调中,我尝试使用 LoadImageFromResource 从资源文件中加载图像二进制文件:

void UserControl1::ImagePropertyChanged( __in IXRDependencyObject* pControl, __in XRValue* pOldValue, __in XRValue* pNewValue )
{
    IWICBitmap *pImage = NULL;
    IXRBitmapImagePtr pBitmap;
    GetXRApplicationInstance(&pApplication);
    pApplication->LoadImageFromResource(App::GetHInstance(), pNewValue->bstrStringVal, L"XAML_RESOURCE", &pImage);

    pApplication->CreateObject(&pBitmap);
    pBitmap->SetSource(pImage);
    pApplication->Release();

    UserControl1 *tempObj;
    pControl->QueryInterface(__uuidof(UserControl1), (void**)&tempObj);
    tempObj->m_pItemImage->SetSource((IXRImageSource*)pBitmap);
}

然而,第二个参数 pResourceName 需要 XRPack 在 .rc 文件中自动生成的资源 ID。例如:

103 XAML_RESOURCE DISCARDABLE "..\\..\\..\\..\\Expression\\Blend_3\\Projects\\WindowsEmbeddedSilverlightApplication1\\WindowsEmbeddedSilverlightApplication1\\img1.png"

那么 pResourceName 应该是 MAKEINTRESOURCE(103)。

由于 XRPack 自动分配 ID,因此我无法动态知道图像名称到 ID 映射。

所以我编写了一个 perl 脚本来处理 .rc 文件并将上面的行转换为:

img1.png XAML_RESOURCE DISCARDABLE "..\\..\\..\\..\\Expression\\Blend_3\\Projects\\WindowsEmbeddedSilverlightApplication1\\WindowsEmbeddedSilverlightApplication1\\img1.png"

在 VS 中,我将脚本配置为在 XRPack 生成 .rc 文件之后和编译开始之前运行。就是那样

LoadImageFromResource(App::GetHInstance(), pNewValue->bstrStringVal, L"XAML_RESOURCE", &pImage);

将工作。

于 2013-12-16T02:03:40.467 回答
0

您可以定义由 XRPack 生成的 ID。为此,请在 XAML 代码中定义:

<Image xrpack:Resource="Source:902(IDR_SETTINGS)" Margin="0" Source="Image.png"/>

如果您使用的是 Expression Blend,您可能还必须为“xrpack”定义命名空间。为此,请在 UserControl 中定义:

mc:Ignorable="d xrpack"
xmlns:xrpack="http://schemas.microsoft.com/windowsembedded/silverlight/packaging"

在 C++ 代码中,您现在可以使用 LoadImageFromResource 方法:

LoadImageFromResource(App::GetHInstance(), MAKEINTRESOURCE(IDR_SETTINGS), L"XAML_RESOURCE", &pImage);
于 2014-02-18T10:46:59.663 回答