5

I am currently developing an application in C# using WPF. What I need to be able to do is on a label make their be an image to the left of the text of the label a small image of an X or a small image of a tick depending on the circumstances. I have got the images included in the project in a folder named images.

How can I assign the images to be placed on the left of the label programatically in the code and not using the XAML code.

3 Answers 3

4

You can either group this inside a grid:

<Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition Width="*" />
  </Grid.ColumnDefinitions>

  <Image Grid.Column="0" Source="{Binding ImageSourceProperty}" />
  <Label Grid.Column="1" Content="{Binding LabelTextProperty}" />
</Grid>

Or, since the label is a content control, you can simply put the image control inside a label control:

<Label>
  <Image Source="{Binding ImageSourceProperty}" />
  My Text
</Label>

Once you know how the xaml should look like, it is very easy to create the same elements via code.

Sign up to request clarification or add additional context in comments.

4 Comments

Your second example doesn't work. ContentControl can only have one child, and you're giving it two (the Image and the text). You would need to wrap a StackPanel around them, e.g. <Label><StackPanel Orientation="Horizontal"><Image Source="{Binding ImageSourceProperty}" /> My Text</Label>
You are right, must not be thinking straight when I wrote that one.
@Joe: Your code doesn't work either - A value of type 'String' cannot be added to a collection or dictionary of type 'UIElementCollection'
@Casebash, you're right -- My Text should have been wrapped in a <TextBlock>...</TextBlock>. Looks like I missed the </StackPanel> too. Oops.
2

Since you want this in code behind and not within XAML I would suggest ditching the Label and using a StackPanel coupled with an Image and TextBlock as seen below where MyGrid could be any container...

        <Grid Name="MyGrid"/>

...then in your code behind...

        StackPanel myStackPanel = new StackPanel();
        myStackPanel.Orientation = Orientation.Horizontal;

        Image myImage = new Image();
        BitmapImage myImageSource = new BitmapImage(); 
        myImageSource.BeginInit();
        myImageSource.UriSource = new Uri("Images/MyImage.png");
        myImageSource.EndInit();
        myImage.Source = myImageSource;

        TextBlock myTextBlock = new TextBlock();
        myTextBlock.Text = "This is my image";

        myStackPanel.Children.Add(myImage);
        myStackPanel.Children.Add(myTextBlock);

        MyGrid.Children.Add(myStackPanel);

Comments

1

I don't agree with the two other answers here. There is no need for a grid to be added to wrap the content. The stackpanel is sufficient.

In the xaml add a stackpanel to where you need the content to be.

<StackPanel Name="myStack" Orientation="Horizontal"></StackPanel>

Then in the code behind, like in a button handler or when the window loads add this

Image coolPic = new Image() { 
    Name="pic", 
    Source = new BitmapImage(new Uri("pack://application:,,,/images/cool.png")), 
    Stretch = Stretch.None  // this preserves the original size, fill would fill
}; 

TextBlock text = new TextBlock() { 
    Name = "myText", 
    Text = "This is my cool Pic" 
};

myStack.Children.Add(coolPic); // adding the pic first places it on the left
myStack.Children.Add(text);    // the text would show up to the right

You can swap the location of the image and the text by adding the text first then the image.

If you don't see the image ensure the image's build action is set to resource in the properties window of the image.

In order for the code to be more useful and or more dynamic you would need a way to change either the text or the image.

So lets say you did want to change those and you go ahead and do a

((TextBlock)FindName("myText")).Text = "my other cool pic";

You would expect the text to be changed but what happens?

Object reference not set to an instance of an object.

Drats but I gave it a name. You would need to add

// register the new control
RegisterName(text.Name, text);

So that you can access the textblock later. This is needed because you added the control to the framework after it was built and displayed. So the final code looks like this after registering the image too

Image coolPic = new Image() { 
    Name="pic", 
    Source = new BitmapImage(new Uri("pack://application:,,,/images/cool.png")), 
    Stretch = Stretch.None // this preserves the original size, fill would fill
};

// register the new control
RegisterName(coolPic.Name, coolPic);

TextBlock text = new TextBlock() {
    Name = "myText",
    Text = "This is my cool Pic" 
};

// register the new control
RegisterName(text.Name, text);

myStack.Children.Add(coolPic);
myStack.Children.Add(text);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.