Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is a custom property in a UserControl not set when the control is used in a DataTemplate?

I have a UserControl that has a custom DependencyProperty. When I use the UserControl from inside a DataTemplate, I cannot set the value of the DependencyProperty. If I use the UserControl directly in a window, then the DependencyProperty works fine. I apologize for the long post, I simplified the code to the minimum that still shows the problem I have in my project. Thanks for any help, I don't know what else to try.

Main Window XAML:

<Window ...>
    <Window.Resources>
        <DataTemplate DataType="{x:Type local:TextVM}">
            <local:TextV MyText="I do not see this"/> <!--Instead I see "Default in Constructor"-->
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <Border BorderThickness="5" BorderBrush="Black" Width="200" Height="100" >
            <StackPanel>
                <ContentControl Content="{Binding Path=TheTextVM}"/>
                <local:TextV MyText="I see this"/>
            </StackPanel>
        </Border>
    </Grid>
</Window>

Main Window Code:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
        TheTextVM = new TextVM();
    }

    public TextVM TheTextVM { get; set; }
}

UserControl XAML:

<UserControl ...>
    <Grid>
        <TextBlock x:Name="textBlock"/>
    </Grid>
</UserControl>

UserControl Code:

public partial class TextV : UserControl
{
    public TextV()
    {
        InitializeComponent();
        MyText = "Default In Constructor";
    }

    public static readonly DependencyProperty MyTextProperty =
       DependencyProperty.Register("MyText", typeof(string), typeof(TextV),
       new PropertyMetadata("", new PropertyChangedCallback(HandleMyTextValueChanged)));

    public string MyText
    {
        get { return (string)GetValue(MyTextProperty); }
        set { SetValue(MyTextProperty, value); }
    }

    private static void HandleMyTextValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
    {
        TextV tv = d as TextV;
        if(tv != null) tv.textBlock.Text = args.NewValue.ToString();
    }
}
like image 690
Carlos Avatar asked Aug 17 '10 21:08

Carlos


1 Answers

The value that you set in code has a higher priority than any value set in XAML.

Instead, you should override the default value in your derived type.

like image 114
SLaks Avatar answered Sep 30 '22 19:09

SLaks