views:

34

answers:

1

Say I have XAML like

<TabControl Grid.Row="1" Grid.Column="2" ItemsSource="{Binding Tabs}" IsSynchronizedWithCurrentItem="True">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding TabTitle}" />
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <local:UserControl1 Text="{Binding Text}" />
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

I want to ask where does the TabTitle and Text properties come from? I think the should come from each item of Tabs right? Say Tabs is a ObservableCollection<TabViewModel> TabTitle & Text should be from TabViewModel properties right. But it seems true to a certain extend. TabTitle is populated correctly while Text is not.

Text is declared as a Dependency Property in UserControl1 as follows

public string Text
{
    get { return (string)GetValue(TextProperty); }
    set { SetValue(TextProperty, value); }
}

public static readonly DependencyProperty TextProperty =
    DependencyProperty.Register("Text", typeof(string), typeof(UserControl1), new UIPropertyMetadata(""));

When I have tabs not bound to a ObservableCollection<TabViewModel> bindings works fine

<TabControl Grid.Row="1" Grid.Column="1">
    <TabItem Header="Tab 1">
        <local:UserControl1 Text="Hello" />
    </TabItem>
    <TabItem Header="Tab 2">
        <local:UserControl1 Text="World" />
    </TabItem>
</TabControl>
A: 

I think I know what is the problem. The element in the UserControl1, which should be filled by Text property, doesn't observe the changes of this property. So there is two ways:

1) Use PropertyChangedCallback:

public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(UserControl1), new UIPropertyMetadata(""),
    new PropertyChangedCallback(OnTextPropertyChanged));

private static void OnTextPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    ((UserControl1)sender).OnTextChanged();
}

private void OnTextChanged()
{
    this.myTextBlock.Text = this.Text;
}

2)Tricky binding:

<UserControl x:Class="UserControl1" x:Name="root" ...>
...
    <TextBlock Text="{Binding Text, ElementName=root}"/>
...
</UserControl>
vorrtex