简体   繁体   中英

Add Label To WPF user Control

That sits by the image. all labels are crowded to the left of the Canvas.I am using some example code for Windows 7 to have an application manipulate images. What I'd like to do is add a label to the bottom of the image. The program generates images on the fly.

Here is the XAML representing the usercontrol for the Picture:

    <UserControl x:Class="DocumentHandlingTouch.Picture"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
    <Image Source="{Binding Path=ImagePath}" Stretch="Fill" Width="Auto" Height="Auto" RenderTransformOrigin="0.5, 0.5">
    <Image.RenderTransform>
        <TransformGroup>
            <RotateTransform Angle="{Binding Path=Angle}"></RotateTransform>
            <ScaleTransform ScaleX="{Binding Path=ScaleX}" ScaleY="{Binding Path=ScaleY}"></ScaleTransform>
            <TranslateTransform X="{Binding Path=X}" Y="{Binding Path=Y}"/>
        </TransformGroup>
    </Image.RenderTransform>
</Image>
<Label VerticalAlignment="Bottom" x:Name="thelabel"/>

Here is a portion of the picture control:

 public partial class Picture : UserControl
{
    public Label label;
    public Picture()
    {
        InitializeComponent();
        DataContext = this;
        label = new Label();
    }

    public string ImagePath
    {
        get { return (string)GetValue(ImagePathProperty); }
        set { SetValue(ImagePathProperty, value); }
    }
}

and this is the code that creates the picture:

 Picture p = new Picture();
 p.ImagePath = path.ToString();
 p.label.Content = p.ImagePath;

This is not working for me because it doesn't really create a label where I can set text on it. Am I going about this wrong? i have posted the code out on OneDrive( http://1drv.ms/1zQy3Or ) in case I am not representing this well enough

As @Ganesh states, it is probably better just to bind to a string.

Just knocked up somthing that might help. There are many ways to do the binding, but this definitely works.

XML

    <Window x:Class="WPF.Window2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window2" Height="300" Width="300"
        x:Name="ViewRoot">
    <Grid>
      <!-- Do image stuff here.-->
      <!-- Put label in appropriate position -->
    <Label Content="{Binding ElementName=ViewRoot, Path=MyLabel}"></Label>
  </Grid>
</Window>

And Code Behind

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WPF
{
    /// <summary>
    /// Interaction logic for Window2.xaml
    /// </summary>
    public partial class Window2 : Window
    {
        public Window2()
        {
            InitializeComponent();
            this.MyLabel = "Hello";
        }



        public string MyLabel
        {
            get { return (string)GetValue(MyLabelProperty); }
            set { SetValue(MyLabelProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MyLabel.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MyLabelProperty =
            DependencyProperty.Register("MyLabel", typeof(string), typeof(Window2), new PropertyMetadata(""));



    }
}

Hope this helps

Whenever I see DataContext = xxxx inside a UserControl, alarm bells go off in my head. Don't do this, please. One of the biggest benefits of WPF/XAML is the separate UI and data layers, and by doing this you are forcing a specific UI-only data layer on a component, which always seems to cause problems in the future because now you can't use any other data with your UserControl.

But I suspect you are not seeing a label on your UI because you haven't actually added it to the UI anywhere.

For example, here's some XAML that places both a TextBlock and Image inside a panel.

<StackPanel>
    <Image Source="{Binding ImagePath}" />
    <TextBlock Text="{Binding ImagePath}" />
</StackPanel>

If you really wanted, you could create this via code behind too.

As for the bindings, do you really need a custom UserControl for this? It seems like something a Template would be fine for too.

<ItemsControl ItemsSource="{Binding MyCollectionOfStrings}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <Image Source="{Binding }" />
                <TextBlock Text="{Binding }" />
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

If you did really want a UserControl, I would create a DependencyProperty of type string for your ImagePath, and bind that to both your Image and Label properties.

<UserControl x:Class="MyNamespace.MyPictureControl"
             x:Name="PictureControl">
    <StackPanel>
        <Image Source="{Binding ImagePath, ElementName=PictureControl}" />
        <TextBlock Text="{Binding ImagePath, ElementName=PictureControl}" />
    </StackPanel>
</UserControl>
public partial class MyPictureControl : UserControl
{
    public MyPictureControl()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty ImagePathProperty =
        DependencyProperty.Register("ImagePath", typeof(string), typeof(MyPictureControl), new PropertyMetadata(null));

    public string ImagePath
    {
        get { return (string)GetValue(ImagePathProperty); }
        set { SetValue(ImagePathProperty, value); }
    }
}

Then anyplace that wants to use this control can either set or bind the ImagePath property

<local:MyImageControl ImagePath="C:\someImage.jpg" />
<local:MyImagecontrol ImagePath="{Binding SomeString}" />

I have tried to create a usercontrol. Please refer the below code.

<UserControl x:Class="DatagridRow_Learning.Picture"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<StackPanel>
    <Image x:Name="image"/>
    <TextBlock x:Name="imageName"/>
</StackPanel>

public partial class Picture : UserControl
{
    public Picture()
    {
        InitializeComponent();            
    }

    public string ImagePath
    {
        get { return (string)GetValue(ImagePathProperty); }
        set { SetValue(ImagePathProperty, value); }
    }

    public static readonly DependencyProperty ImagePathProperty =
        DependencyProperty.Register("ImagePath", typeof(string), typeof(Picture), new PropertyMetadata(string.Empty, new PropertyChangedCallback(ImagePathCallBack)));

    private static void ImagePathCallBack(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        Picture pic = obj as Picture;
        pic.image.Source= new BitmapImage(new Uri((string)args.NewValue));
    }

    public string ImageLabel
    {
        get { return (string)GetValue(ImageLabelProperty); }
        set { SetValue(ImageLabelProperty, value); }
    }

    public static readonly DependencyProperty ImageLabelProperty =
        DependencyProperty.Register("ImageLabel", typeof(string), typeof(Picture), new PropertyMetadata(string.Empty,new PropertyChangedCallback( ImageLabelCallBack)));

    private static void ImageLabelCallBack(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        Picture pic = obj as Picture;
        pic.imageName.Text= (string)args.NewValue;
    }        
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM