简体   繁体   English

Windows Embedded的Silverlight:如何在xaml和后台代码之间传递imagesource依赖项属性

[英]Silverlight for Windows Embedded: how to communicate imagesource Dependency Property between xaml and code-behind

I am working on a Silverlight for Windows Embedded project. 我正在从事Silverlight for Windows Embedded项目。 I defined a custom user control which consists of an image control. 我定义了一个由图像控件组成的自定义用户控件。 I want to specify different image source in xaml for different instance of the custom control. 我想在xaml中为自定义控件的不同实例指定不同的图像源。 So I define a Dependency Property "MyImage" in the custom control. 因此,我在自定义控件中定义了一个依赖项属性“ MyImage”。

In the Blend C# code-behind: public UserControl1() { InitializeComponent(); 在后面的Blend C#代码中:public UserControl1(){InitializeComponent(); ItemImage.DataContext = this; ItemImage.DataContext = this; } }

    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);

In UserControl.xaml I bind the image control Source property to MyImage: 在UserControl.xaml中,将图像控件的Source属性绑定到MyImage:

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

So when I use the custom control I can do this in xaml: 因此,当我使用自定义控件时,可以在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"/>

Testing in Blend is ok. 在Blend中测试可以。 I can see the two images shown in the two custom control instance. 我可以看到两个自定义控件实例中显示的两个图像。

Then coming to SWE C++ code-behind, I redefined and register the Dependency Property in UserControl1.cpp: 然后进入SWE C ++代码隐藏,我重新定义并在UserControl1.cpp中注册Dependency属性:

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 )
{......}

The compilation and execution is successful, just that I don't see images being displayed in the two controls. 编译和执行成功,只是在两个控件中看不到图像。

When debugging, I can see the ConvertNameTypeConverter callback is first invoked. 调试时,我可以看到首先调用ConvertNameTypeConverter回调。 I can see the image file name is stored in pValIn as a string, which is inline with what MSDN documentation describes: When XAML for Windows Embedded calls this function in the parsing phase, pValIn will always be a string. 我可以看到图像文件名以字符串形式存储在pValIn中,这与MSDN文档描述的内容一致:当Windows Embedded的XAML在解析阶段调用此函数时,pValIn将始终是字符串。

Next the ImagePropertyChanged callback is invoked, and I can see pNewValue contains the values I set to pValOut in ConvertNameTypeConverter(). 接下来,调用ImagePropertyChanged回调,并且我可以看到pNewValue包含我在ConvertNameTypeConverter()中设置为pValOut的值。

My question is, am I doing the correct way? 我的问题是,我做对了吗? If I can only get a string for the image file name, how can I get the image binary from the string? 如果只能获取图像文件名的字符串,如何从字符串中获取图像二进制文件?

Is there a way to directly transfer the image binary from xaml to C++ code-behind and display directly? 有没有一种方法可以将图像二进制文件从xaml直接传输到C ++代码隐藏并直接显示?

Thanks! 谢谢!

Problem solved. 问题解决了。 But I think my solution looks like just a workaround. 但是我认为我的解决方案似乎只是一种解决方法。 In the callback I tried to use LoadImageFromResource to load the image binary from resource file: 在回调中,我尝试使用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);
}

However the 2nd argument pResourceName expects a resource ID automatically generated by XRPack in .rc file. 但是,第二个参数pResourceName需要XRPack自动在.rc文件中生成的资源ID。 For eg: 例如:

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

Then pResourceName should be MAKEINTRESOURCE(103). 然后,pResourceName应该为MAKEINTRESOURCE(103)。

Since the ID is automatically assigned by XRPack, there is no way for me to know the image name to ID mapping dynamically. 由于ID是由XRPack自动分配的,因此我无法动态知道映像名称到ID的映射。

So I write a perl script to process .rc file and convert the above line into: 因此,我编写了一个perl脚本来处理.rc文件,并将上述行转换为:

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

In VS I configure the script to run after XRPack generates .rc file and before compilation starts. 在VS中,我将脚本配置为在XRPack生成.rc文件之后并且在编译开始之前运行。 That is how 就是那样

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

will work. 将工作。

You can define IDs which are generated by XRPack. 您可以定义XRPack生成的ID。 To do that, define in your XAML Code: 为此,请在您的XAML代码中定义:

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

If you are using Expression Blend, you will probably also have to define namespace for "xrpack". 如果使用的是Expression Blend,则可能还必须为“ xrpack”定义名称空间。 To do that, define in UserControl: 为此,请在UserControl中定义:

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

In C++ code you can now use LoadImageFromResource method: 在C ++代码中,您现在可以使用LoadImageFromResource方法:

LoadImageFromResource(App::GetHInstance(), MAKEINTRESOURCE(IDR_SETTINGS), L"XAML_RESOURCE", &pImage);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 用于Windows的Silverlight嵌入式 - Silverlight for windows embedded 如何在Windows Embedded的Silverlight中使用C ++为多个按钮实现代码 - How to implement code for multiple buttons using c++ in Silverlight for Windows Embedded 请帮助我检查有关Windows Embedded Silverlight中数据绑定的代码 - Please help me check the code about Databinding in Silverlight for Windows Embedded 如何在Windows上使用C ++和PHP进行通信? - How to communicate between C++ and PHP on Windows? 如何在嵌入式浏览器和网页端之间进行双向通信 - How to communicate both ways between embedded browser and webside 如何在“ Windows Embedded的XAML(Compact 2013)”中切换图像 - How do I switch an image in “XAML for Windows Embedded (Compact 2013)” 使用WEST工具嵌入Windows的Silverlight - Silverlight for windows embedded using WEST tool Silverlight for Windows Embedded(SWE)中的数据绑定 - Data binding in Silverlight for Windows Embedded (SWE) 在Windows Embedded的Silverlight中实现图形的硬件加速 - Implement Hardware Acceleration for Graphics in Silverlight for Windows Embedded 适用于Windows Embedded 7的Silverlight中的多页应用程序 - Multi-page application in Silverlight for Windows Embedded 7
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM