Question

I have a UserControl that has some properties that I wish to bind to XAML.

<UserControl x:Class="UserControl1"
             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" DataContext="{RelativeSource Self}">
<UserControl.Background>
    <ImageBrush ImageSource="{Binding BackgroundImage}" Stretch="UniformToFill" AlignmentX="Center" AlignmentY="Bottom"/>
</UserControl.Background>

<Grid Name="mainGrid">
    <Label Canvas.ZIndex="-1" Foreground="Gray" Content="{Binding VersionNumber}" Height="28" HorizontalAlignment="Left" Name="versionLabel" VerticalAlignment="Bottom" />
</Grid>
</UserControl>

And code-behind:

public partial class UserControl1 : UserControl, INotifyPropertyChanged
{
    public string VersionNumber { private get; set; }
    public ImageSource BackgroundImage { private get; set; }

    public UserControl1()
    {
        InitializeComponent();
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

}

I have a window that contains the UserControl, like so

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SomeNameSpace"

        Title="MainWindow" 
        MinHeight="400" MinWidth="400" >
<local:UserControl1 BackgroundImage="images\background.png" VersionNumber="10"/>

Of course, the actual window does not show anything, the background is blank and the Label.Content is null, but the Autos window shows me that the properties have been set correctly, like this. Autos

I've been messing with this for the past 2 hours or so, I don't know whats going wrong.

EDIT I've tried this

 private string versionNumber;
 public string VersionNumber { get { return this.versionNumber; } 
 set { 
      this.versionNumber = value; 
      OnPropertyChanged("VersionNumber"); 
  } 
}

And it still doesn't work, the label in this case does not update.

result

Was it helpful?

Solution

You should use this for label binding:

Content={Binding RelativeSource= {RelativeSource FindAncestor, AncestorType={x:Type wpfApplication1:UserControl1}}, Path=VersionNumber}

UserControl1 is the name of your user control class. You have to specify the namespace and the user control.

You can keep your private get it still works with this binding.

EDIT Following your code I made this demo:

//window.xaml

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:wpfApplication1="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <wpfApplication1:UserControl1 VersionNumber="10"/>
</Grid>

//UserControl1

<UserControl x:Class="WpfApplication1.UserControl1"
         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"
         xmlns:wpfApplication1="clr-namespace:WpfApplication1"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" DataContext="{RelativeSource Self}">
<UserControl.Background>
    <ImageBrush ImageSource="{Binding BackgroundImage}" Stretch="UniformToFill" AlignmentX="Center" AlignmentY="Bottom"/>
</UserControl.Background>

<Grid Name="mainGrid">
    <Label Canvas.ZIndex="-1" Foreground="Gray" Content="{Binding RelativeSource= {RelativeSource FindAncestor, AncestorType={x:Type wpfApplication1:UserControl1}}, Path=VersionNumber}" 
           Height="28" HorizontalAlignment="Left" Name="versionLabel" VerticalAlignment="Bottom" />
</Grid>

UserControl1.cs

public partial class UserControl1 : UserControl, INotifyPropertyChanged
{
    private string _versionNumber;
    private ImageSource _backgroundImage;

    public UserControl1()
    {
        InitializeComponent();
    }

    public string VersionNumber
    {
        private get { return _versionNumber; }
        set
        {
            _versionNumber = value;
            OnPropertyChanged("VersionNumber");
        }
    }

    public ImageSource BackgroundImage
    {
        get { return _backgroundImage; }
        set
        {
            _backgroundImage = value;
            OnPropertyChanged("BackgroundImage");
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

As @anees suggested you can also use dependency properties for VersionNumber and BackgroundImage:

public static readonly DependencyProperty VersionNumberProperty = DependencyProperty.Register(
        "VersionNumber", typeof (string), typeof (UserControl1), new PropertyMetadata(default(string)));

    public string VersionNumber
    {
        get { return (string) GetValue(VersionNumberProperty); }
        set { SetValue(VersionNumberProperty, value); }
    }

public static readonly DependencyProperty BackgroundImageProperty = DependencyProperty.Register(
        "BackgroundImage", typeof (ImageSource), typeof (UserControl1), new PropertyMetadata(default(ImageSource)));

    public ImageSource BackgroundImage
    {
        get { return (ImageSource) GetValue(BackgroundImageProperty); }
        set { SetValue(BackgroundImageProperty, value); }
    }

OTHER TIPS

I feel you haven't properly include the Usercontrol in MainWindow, Include the following namespace in your MainWindow

xmlns:local="clr-namespace:YourNameSpace"

And add your Usercontrol like as follows:

<local:UserControl1 x:Name="somename" .... />

May be datacontext issues because if that show's null then the context is not set properly

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top