views:

68

answers:

6

Am i missing something here? I have created a usercontrol with a property and for arguments sake it has a text box in it.

<UserControl x:Class="Isd.Utility.SystemMonitorWpf.Bar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;

<TextBlock x:Name="txtExpected" Grid.Column="0" Grid.ColumnSpan="2" Width="auto" Height="auto" FontSize="10" LayoutTransform="{StaticResource Rotate}" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Tahoma" Foreground="Red" Panel.ZIndex="100" Margin="5,5,5,5"/>

Then in the code behind i have

public partial class Bar : UserControl
{
    private string _PropTest;

    public string PropTest
    {
        get { return _PropTest; }
        set { _PropTest = value; }
    } 

public Bar()
    {
        InitializeComponent();
        txtExpected.Text = PropTest;
    }
}

Then i drop the usercontrol into the xaml and set the property to a value

<local:Bar PropTest="test"></local:Bar>

In this example, when the usercontrol is displayed the text is showing as null, its like the property PropTest never got set. Am I missing something obvious here? Thanks in advance.

A: 

When used as an attribute like you have it, PropTest gets set after the constructor is called, so it doesn't get set when you apply the property to the text box.

You'd be better attaching an event to the property changing, or use the TextBox as the backing value for the property.

Program.X
The assignment `PropTest="test"` should be a part of InitializeComponent (since it parses the XAML), so at the nxet line of constructor it must be _already_ set.
Vlad
@Vlad Good point. Thanks.
Program.X
A: 

What happens when you add Text attribute like so:

<TextBlock x:Name="txtExpected" Text="{Binding PropTest}" />

and eliminate the line

txtExpected.Text = PropTest;

from the constructor?

slugster
@Steven, you don't have to have a dependency property for binding sources...
Anvaka
@Slugster, some evil went through our answers and gave us a slap :). Though answers were correct :).
Anvaka
I agree :) None of the binding sources in my ViewModels are dependency properties. Hopefully @Steven will reverse his itchy down-voting finger and reverse his vote (if it was him that down voted).
slugster
Sorry, of course you are right, it's the destination that has to be a DP.. I blame the fact I have a smacking headache :-P
Steven Robbins
Still not sure it would work though without INPC or being a DP.. the binding may get its initial value before the property is set.
Steven Robbins
A: 

Delegate value assignment in PropTest property to TextBox:

public string PropTest
{
    get { return txtExpected.Text; }
    set { txtExpected.Text = value; }
} 
Anvaka
Thank you for the minus, secret hero... I never liked 4 at the end of my rating :).
Anvaka
A: 

You don't appear to be doing anything in the setter of PropTest. It won't be set prior to construction, so it will be null when you do:

txtExpected.Text = PropTest;

Inside your constructor. If you do this:

public string PropTest
{
    get { return _PropTest; }
    set 
    { 
        _PropTest = value; 
        txtExpected.Text = PropTest;
    }
} 

It should work. It's not what I'd call an "ideal" way to do things though, you might want to take a look at Dependency Properties, INotifyPropertyChanged and Binding.

Steven Robbins
Well, but why the _original_ code doesn't work?
Vlad
I've told you why it doesn't work, because you are setting txtExpected.Text *in the constructor only* and at that point the value of the property is null!
Steven Robbins
IMHO you are not completely correct here, the property will be set as a part of `InitializeComponent()`, because this procedure parses the XAML. So after that line assignment must work.
Vlad
Thanks Steven, you're right here, I am stuck in the web world thinking it would just work, I changed my example from a Dependency property to make it easier to describe but now i'll look at doing it the "right" way, thanks :-)
Coesy
A: 

It's because the value of the attribute will never set on the Text-Property of the txtExpected-Control. At the time when the constructor is called, the property PropTest still null.

So, you have to change the implementation of your property:

public string PropTest
{
    get { return txtExpected.Text; }
    set { txtExptected.Text = value; }
}
p2u
Should it be not assigned as a part of `InitializeComponent()`?
Vlad
A: 

You should use DependencyProperties, so you can bind your control properties via xaml

On your class declaration:

    public static readonly DependencyProperty MyProperty = DependencyProperty.Register(
        "MyProperty",                  //Property name
        typeof(string),                //Property type
        typeof(MyControl),             //Type of the dependency property provider
        new PropertyMetadata(MyPropertyChanged));//Callback invoked on property value has changes

    public string MyProperty
    {
        set
        {
            this.SetValue(MyProperty, value);
        }
        get
        {
            return (string)this.GetValue(MyProperty);
        }
    }

    private static void MyPropertyChanged( object sender, DependencyPropertyChangedEventArgs args )
    {
      // update your control inner elements properties
    }

Edited a few times because of typos :P

Orestes C.A.
this is brilliant, but // update your control inner elements properties doesn't allow me to access my txtExpected object to be able to set the inner elements.
Coesy