none
C++中Image图片如何画到界面上 RRS feed

  • 问题

  • 我想实现的功能是把已有的图片(文件夹下的图片)画到界面上,不借助任何控件,比如Image、Button控件,是否可以不用D2D就可以实现

    如果上述方法不行,那么在Image控件的click事件中是否可以对Image->Margin属性进行赋值,来改变Image控件的位置?谢谢

    关于Margin,我只会在XAML中设置他的参数,不知道如何在后台(C++程序中)设置。如下方法不可以:ImageCard1->Margin(10,101,10,10);

    2012年6月12日 8:58

答案

  • 设置 Margin C++代码:

    element->Margin = ref new Thickness(10,10,10,10);  // 看文档 http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.thickness 四个参数分别是Left, Top, Right, and Bottom 值,简单记忆,就是从左顺时针方向。

    ImageBrush他是个Brush, 画刷,可作为一个元素的背景前景等填充色。 ImageBrush就是可以把一个图片做为画刷来填充。

    一旦你会用XAML了,你就应该去学会怎么用代码去写一样的XAML。 所以我一般都会建议大家去先了解和学习下WPF或者Silverlight, 这些概念是完全一样的。

    XAML中的一个<Element>出来,就相当于我们通过代码创建了一个Element 类型的对象,如:

    <Rectangle>
     
    <Rectangle.Fill>
       
    <ImageBrush... />
     
    </Rectangle.Fill>
    </Rectangle>

    的C++是:

    	Rectangle^ rect = ref new Rectangle(); // <Rectangle> ... </Rectangle>
    	rect->Fill = ref new ImageBrush(); // <Rectangle.Fill><ImageBrush ... /></Rectangle.Fill>
    

    -----------------------

    ImageBrush 没有Margin属性,所以你对ImageBrush 设置是无效的。

    但Image控件有。

    -----------------------

    回到你的第一个问题,“改变Image控件的位置”?

    首先我不知道你是否理解为什么在Grid中的Image需要通过Margin来改变位置。  Grid布局的默认行为让他里面的元素填充,一旦元素填充了,就只能通过边距Margin属性来控制元素显示的位置。或者水平/竖直对齐方式的属性也可以影响元素的位置。

    Canvas布局的行为就不一样,他是通过Canvas.Left/Top/Right/Bottom四个附加属性来控制一个元素的位置的,当然内边距/外边距也是有一定效果的。

    关于布局,我建议还是先看看WPF布局系统的解释:http://msdn.microsoft.com/zh-cn/library/ms745058.aspx 这点Metro和WPF是一致的。

    所以,你所谓的“改变Image控件的位置”,如果在Grid中,则使用通过改变Margin, 如果是Canvas,则可以是Canvas.Left/Top/Right/Bottom:

    img->SetValue(Canvas::LeftProperty, 100 /*value*/);  等


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年6月13日 9:00
    版主
  • 不好意思,结构体不需要引用了,去掉 ref new:

    img->Margin = Thickness(100,100,100,100);


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年6月14日 10:29
    版主
  • 当然可以,就如我之前回复中说的: XAML中的一个<Element>出来,就相当于我们通过代码创建了一个Element 类型的对象

    在这个帖子中你已经学会了 如何通过代码给Image附上图片:http://social.msdn.microsoft.com/Forums/zh-CN/metroappzhcn/thread/de38af3a-9577-48c4-8da6-7fca69a8c3b9/#5d973ac2-2b78-414f-be77-0590d6fc2d39

    然后我们要做的只是创建Image实例: Image^ img = ref new Image();  将其加到界面的某一个布局或者控件中, 下面例子我命名了根Grid为RootGrid:

    <Page
        x:Class="App4.MainPage"
        IsTabStop="false"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App4"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid x:Name="RootGrid"  Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    
        </Grid>
    ....

    后台代码创建Image加入Grid:

    	BitmapImage^ bitmapImage =ref new BitmapImage(); 
        bitmapImage->UriSource =ref new Uri(Package::Current->InstalledLocation->Path + "/Assets/" + "Logo.png");
    	
    	Image^ img = ref new Image();
    	img->Source = bitmapImage;
    	RootGrid->Children->Append(img);


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年6月15日 3:15
    版主

全部回复

  • Bob Bao,你好,上次你回复的相关答复如下 

    ImageBrush, fill一个Rectangle。

    <Rectangle>
      <Rectangle.Fill>
        <ImageBrush ... />
      </Rectangle.Fill>
    </Rectangle>
    Margin Thickness 类型,这样就行了
       element.Margin = new Thickness(...);

     ImageBrush是在XAMl里操作的吧,我不太明白他的作用, 还有就是 element.Margin = new Thickness(...);这个括号里应该怎么填写如下(10,10,10,10)不可以吧.那该如何操作呢?

    2012年6月12日 9:03
  • 设置 Margin C++代码:

    element->Margin = ref new Thickness(10,10,10,10);  // 看文档 http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.thickness 四个参数分别是Left, Top, Right, and Bottom 值,简单记忆,就是从左顺时针方向。

    ImageBrush他是个Brush, 画刷,可作为一个元素的背景前景等填充色。 ImageBrush就是可以把一个图片做为画刷来填充。

    一旦你会用XAML了,你就应该去学会怎么用代码去写一样的XAML。 所以我一般都会建议大家去先了解和学习下WPF或者Silverlight, 这些概念是完全一样的。

    XAML中的一个<Element>出来,就相当于我们通过代码创建了一个Element 类型的对象,如:

    <Rectangle>
     
    <Rectangle.Fill>
       
    <ImageBrush... />
     
    </Rectangle.Fill>
    </Rectangle>

    的C++是:

    	Rectangle^ rect = ref new Rectangle(); // <Rectangle> ... </Rectangle>
    	rect->Fill = ref new ImageBrush(); // <Rectangle.Fill><ImageBrush ... /></Rectangle.Fill>
    

    -----------------------

    ImageBrush 没有Margin属性,所以你对ImageBrush 设置是无效的。

    但Image控件有。

    -----------------------

    回到你的第一个问题,“改变Image控件的位置”?

    首先我不知道你是否理解为什么在Grid中的Image需要通过Margin来改变位置。  Grid布局的默认行为让他里面的元素填充,一旦元素填充了,就只能通过边距Margin属性来控制元素显示的位置。或者水平/竖直对齐方式的属性也可以影响元素的位置。

    Canvas布局的行为就不一样,他是通过Canvas.Left/Top/Right/Bottom四个附加属性来控制一个元素的位置的,当然内边距/外边距也是有一定效果的。

    关于布局,我建议还是先看看WPF布局系统的解释:http://msdn.microsoft.com/zh-cn/library/ms745058.aspx 这点Metro和WPF是一致的。

    所以,你所谓的“改变Image控件的位置”,如果在Grid中,则使用通过改变Margin, 如果是Canvas,则可以是Canvas.Left/Top/Right/Bottom:

    img->SetValue(Canvas::LeftProperty, 100 /*value*/);  等


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年6月13日 9:00
    版主
  • 感谢 Bob Bao!但是我对Image的Margin属性还是不能操作,以下方法不对么?

    Image imagemyCard;     //定义一个Image类型的对象
     imagemyCard.Source =imageCards2->GetAt(0);  //给imagemyCard赋值,将图片路径赋值过来,imageCards2类型 ref new Platform::Collections::Vector<BitmapImage^>();
     imagemyCard.Margin = ref new Thickness(100,100,100,100);  //会出错  error C2664: “Windows::UI::Xaml::FrameworkElement::Margin::set”: 不能将参数 1 从“Windows::UI::Xaml::Thickness *”转换为“Windows::UI::Xaml::Thickness”

    在C++中不能对Image 的 Margin属性操作么?我的imagemyCard不是Image控件的name,是Image 的对象。

    2012年6月14日 8:16
  • 即使我用Image控件做如上赋值 image1->Margin =ref new Thickness(10,10,10,10);  也还是报这个error

    C2664: “Windows::UI::Xaml::FrameworkElement::Margin::set”: 不能将参数 1 从“Windows::UI::Xaml::Thickness *”转换为“Windows::UI::Xaml::Thickness”

    2012年6月14日 8:18
  • 不好意思,结构体不需要引用了,去掉 ref new:

    img->Margin = Thickness(100,100,100,100);


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年6月14日 10:29
    版主
  • 哦,OK了,多谢Bob Bao!

    还有个小问题,我可以用C++代码动态创建Image控件么?

    2012年6月14日 11:26
  • 当然可以,就如我之前回复中说的: XAML中的一个<Element>出来,就相当于我们通过代码创建了一个Element 类型的对象

    在这个帖子中你已经学会了 如何通过代码给Image附上图片:http://social.msdn.microsoft.com/Forums/zh-CN/metroappzhcn/thread/de38af3a-9577-48c4-8da6-7fca69a8c3b9/#5d973ac2-2b78-414f-be77-0590d6fc2d39

    然后我们要做的只是创建Image实例: Image^ img = ref new Image();  将其加到界面的某一个布局或者控件中, 下面例子我命名了根Grid为RootGrid:

    <Page
        x:Class="App4.MainPage"
        IsTabStop="false"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App4"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid x:Name="RootGrid"  Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    
        </Grid>
    ....

    后台代码创建Image加入Grid:

    	BitmapImage^ bitmapImage =ref new BitmapImage(); 
        bitmapImage->UriSource =ref new Uri(Package::Current->InstalledLocation->Path + "/Assets/" + "Logo.png");
    	
    	Image^ img = ref new Image();
    	img->Source = bitmapImage;
    	RootGrid->Children->Append(img);


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年6月15日 3:15
    版主
  • 多谢Bob Bao,现在可以动态创建Image了,还有个小问题,我现在也可以动态创建Button,但是怎么将Button的背景设置图片呢,如下方法不可以:

    BitmapImage^ bitmapImage =ref new BitmapImage();
        bitmapImage->UriSource =ref new Uri(Package::Current->InstalledLocation->Path + "/Assets/" + "1.png");
     Button^ buttonCard1 = ref new Button();
     buttonCard1->DataContext = bitmapImage;  //当ButtonCard1是已经创建好的Button时,ImageSource属性设置为数据上下文 关联时可以使用,但是他是动态的时候无效,Button是空的不能显示图片1.png,原因是什么呢?
     buttonCard1->Width = 100;
     buttonCard1->Height = 100;
     ImageGrid->Children->Append(buttonCard1);

    Button在C++中找不到ImageSource属性呢?

    2012年6月15日 6:35
  • 数据上下文是提供给数据绑定以默认的数据对象,你这里并不是用绑定来关联所以不需要数据上下文,直接将 Button->Content设置为你的Image组件即可:

    	BitmapImage^ bitmapImage =ref new BitmapImage(); 
    	bitmapImage->UriSource =ref new Uri(Package::Current->InstalledLocation->Path + "/Assets/" + "Logo.png");
    	Image^ img = ref new Image();	
    	img->Source = bitmapImage;
    	Button^ buttonCard1 = ref new Button();
    	buttonCard1->Content = img;
    	ImageGrid->Children->Append(buttonCard1);

    或者你也可以用绑定来实现:

    	BitmapImage^ bitmapImage =ref new BitmapImage(); 
    	bitmapImage->UriSource =ref new Uri(Package::Current->InstalledLocation->Path + "/Assets/" + "Logo.png");
    
    	Button^ buttonCard1 = ref new Button();
    	buttonCard1->DataContext = bitmapImage;
    
    	Image^ img = ref new Image();	
    	img->SetBinding(Image::SourceProperty, ref new Binding());
    	buttonCard1->Content = img;
    	ImageGrid->Children->Append(buttonCard1);

    或者用ImageBrush fill Button背景(背景的方式,在鼠标移上后由于按钮本身的背景色处理,会将你设置的覆盖掉,导致看不见):

    	BitmapImage^ bitmapImage =ref new BitmapImage(); 
    	bitmapImage->UriSource =ref new Uri(Package::Current->InstalledLocation->Path + "/Assets/" + "Logo.png");
    
    	Button^ buttonCard1 = ref new Button();
    
    	ImageBrush^ imgbrush = ref new ImageBrush();	
    	imgbrush->ImageSource = bitmapImage;
    
    	buttonCard1->Background = imgbrush;
    	buttonCard1->Width = 100;
    	buttonCard1->Height = 100;
    	ImageGrid->Children->Append(buttonCard1);



    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年6月15日 10:07
    版主
  • 好的,谢谢了!问个和这个无关的,Metro 的 C++中有List么,怎么定义呢?有相关例子么?谢谢!
    2012年6月15日 11:00
  • 现在我遇到的问题时如下定义不可以: Platform::Collections::Vector<Array<int>>^ CardManager;

    Vector不可以包含Array<int>类型的数组,但是实际上原来的List是可以包括的,现在我想使用原来C++中的List类或者ArrayList<> 怎么定义呢?

    2012年6月15日 11:12
  • 你是要List中每个元素是一个数组对吧, 多级的集合, 但是CX里面的容器不支持多级数组,所以在语法上这个通不过,不过你可以用Object^去捕获Array<int>^

    int nums1[] = {0,1,2,3,4};
    int nums2[] = {10,11,12,13,14,15};
    
    Platform::Collections::Vector<Platform::Object^>^ CardManager = 
    ref new Platform::Collections::Vector<Platform::Object^>();
    
    Array<int>^ arr1 = ref new Array<int>(nums1, 5); 
    Array<int>^ arr2 = ref new Array<int>(nums2, 6);
    
    CardManager->Append(arr1);
    CardManager->Append(arr2);
    


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年6月18日 5:16
    版主
  • 哦,多谢Bob Bao!
    2012年6月18日 11:01