views:

2069

answers:

5

I created a user control in WPF:

<UserControl x:Class="TestUserControl.Controls.GetLatest"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
        <TextBlock Name="theTextBlock"/>
</UserControl>

The code behind has a parameter called "FirstMessage" which it sets as the text of my user control TextBlock:

public partial class GetLatest : UserControl
{
    public string FirstMessage { get; set; }

    public GetLatest()
    {
        InitializeComponent();
        theTextBlock.Text = this.FirstMessage;
    }
}

In my main code I can set the FirstMessage parameter in my user control with intellisense:

<Window x:Class="TestUserControl.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300"
    xmlns:controls="clr-namespace:TestUserControl.Controls"
    >
    <StackPanel>
        <controls:GetLatest FirstMessage="This is the title"/>
    </StackPanel>
</Window>

However, it still doesn't set the text. I've tried Text="{Binding Path=FirstMessage}" and other syntaxes I have found but nothing works.

How can I access the FirstMessage value in my user control?

+3  A: 

FirstMessage is set after the constructor has been called. You should change your Text from the setter of FirstMessage.

When initializing object from XAML, first the default constructor is called, then the properties are set on the object.

Bubblewrap
A: 

In the case of the code you posted above it is a timing issue; the FirstMessage property has not had its value assigned when the constructor executes. You'd have to execute that code in an event occuring later on such as Loaded.

Richard C. McGuire
+2  A: 

This quick example won't use any binding because the value isn't set up until after the Default Constructor is called, but here's how you can get the text to show up.

<UserControl x:Class="TestUserControl.Controls.GetLatest"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Loaded="GetLatest_Loaded">
        <TextBlock Name="theTextBlock"/>
</UserControl>

Then, just modify your cs file to this:

public partial class GetLatest : UserControl
{
    public string FirstMessage { get; set; }

    public GetLatest()
    {
        InitializeComponent();
        theTextBlock.Text = this.FirstMessage;
    }

    private void GetLatest_Loaded(object sender, RoutedEventArgs e)
    {
        theTextBlock.Text = this.FirstMessage;
    }
}

I recommend working on setting up a Binding instead, as this is fairly spaghetti-like code.

KP Adrian
+6  A: 

Your approach to binding doesn't work because your property FirstMessage doesn't notify when it gets updated. Use Dependency Properties for that. See below:

public partial class GetLatest : UserControl
{
    public static readonly DependencyProperty FirstMessageProperty = DependencyProperty.Register("FirstMessage", typeof(string), typeof(GetLatest));

    public string FirstMessage
    {
        get { return (string)GetValue(FirstMessageProperty); }
        set { SetValue(FirstMessageProperty, value); }
    }

    public GetLatest()
    {
        InitializeComponent();
        this.DataContext = this;
    }

}

XAML:

<UserControl x:Class="TestUserControl.Controls.GetLatest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <TextBlock Text="{Binding FirstMessage}" />
</UserControl>

Whenever the FirstMessage property changes, your text block will update itself.

siz
yes! exactly what I was looking for, thanks!
Edward Tanguay
I tried your solution and got the error "Logical tree depth exceeded while traversing the tree. This could indicate a cycle in the tree." but when i remove the line this.DataContext = this; the error disappears but the binding will not work. What is the problem here?
Tri Q
@Tri Q: I'm seeing the logical tree depth exception as well but in different code. Doesn't seem to be much material regarding this error on the web so I'm curious if you could respond if you have found a solution.
jpierson
A: 

You can also use:

public partial class GetLatest : UserControl
{
    private string _firstMessage;
    public string FirstMessage 
    {
        get { return _firstMessage; }
        set { _firstMessage = value; theTextBlock.Text = value; }
    }

    public GetLatest()
    {
        InitializeComponent();
    }
}
Nir