MikeC
MikeC

Reputation: 284

Problem databinding with WPF

Been beating my head against a wall and figured it was time to post a question. I have the following user control

XAML

<UserControl x:Class="WorkDayManager3.WPF.UserControls.TimeControl"
         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="46" d:DesignWidth="133" Background="Transparent"
         DataContext="{Binding RelativeSource={RelativeSource self}}">    
<Grid Height="44" Width="132" Background="Transparent">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="29" />            
    </Grid.ColumnDefinitions>

    <TextBox Name="label" Text="{Binding Text}" Grid.ColumnSpan="5"></TextBox>

</Grid>

C#

public partial class TimeControl : UserControl
{
    public string Text
    {

        get { return (string)GetValue(TextProperty); }

        set { SetValue(TextProperty, value); }

    }

    // Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc...

    public static readonly DependencyProperty TextProperty =

    DependencyProperty.Register("Text", typeof(string), typeof(TimeControl), new UIPropertyMetadata("N/A"));

    public TimeControl()
    {
        InitializeComponent();
    }

In the Window where i use the control it is used in a grid with its datacontext set to a StaticResource

    <Grid Grid.Row="1" HorizontalAlignment="Center" DataContext="{StaticResource shiftViewSource}" Name="grid1" Margin="48,10,38,0">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <TextBox Grid.Column="0" Grid.Row="1" Height="23" TabIndex="2" HorizontalAlignment="Left" Margin="10,5,0,5" Name="shiftNameTextBox" Text="{Binding Path=ShiftName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="120" />
        <my2:TimeControl Grid.Column="0" Grid.Row="2" Height="23" TabIndex="2" HorizontalAlignment="Left" Margin="10,5,0,5" Name="shiftNameTextBox" Text="{Binding Path=ShiftName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="120" />
        <my2:TimeControl Grid.Column="0" Grid.Row="3" Text="THIS WORKS OK"/>            
    </Grid>

Now the TextBox that is Bound to Path ShiftName works fine and displays the text. When i use my control instead it doesn't show the expected text. However in the second example where i just set the Text dependency property to "THIS WORKS OK" the text shows up as expected. Why does the binding work for the TextBox but not my control. What am i doing wrong?

Upvotes: 2

Views: 194

Answers (2)

Kent Boogaart
Kent Boogaart

Reputation: 178660

You've set the DataContext on the UserControl to itself. Thus, the binding of your TimeControl's Text property is attempting to find a property called ShiftName on your TimeControl, not on your static resource. If you look in the output window of visual studio, you should see an error message to that effect.

It is never a good idea to set the DataContext on the UserControl anyway, because anyone could override it. You could just do this instead:

<UserControl x:Name="root" ...>
    <Grid DataContext="{Binding ElementName=root}"
        ...

Upvotes: 6

Emond
Emond

Reputation: 50672

An other way might be to use a Relative binding:

<Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" >
    ...

Upvotes: 0

Related Questions