2

A UserControl has 3 Dependency Properties: FormatAvailabilities, Orientation and FullText. FormatAvailabilities is bound to the ItemsSource property of an ItemsControl. Orientation is bound to the Orientation property if the StackPanel which is in the ItemsPanelTemplate within the ItemsControl. FullText is bound to the Visibility property of two TextBlocks inside the DataTemplate of the ItemsControl. I am using two converters to determine which TextBlock to show: a BoolToVisibilityConverter and a BoolToInvertedVisibilityConverter (the latter is an inversion of the former). I copied the Visibility property as-is from the TextBlock (both of them, independently) to the ItemsControl and it works correctly..

It seems that the bindings on the TextBlocks are not working properly because both are always visible. Since they are both binding on the same property but one is inverted, there should never be a possibility for both to be visible at the same time.

I put a breakpoint in my converter and it is never hit, so my guess is that there is an issue with binding from within a repeating control to the outer control in which it is housed.

App.xaml:

<common:BaseApp x:Class="xyz.App" xmlns:converters="clr-namespace:xyz.Converters;assembly=xyz">
    <common:BaseApp.RootVisual>
        <phone:PhoneApplicationFrame x:Name="RootFrame" Source="/Home.xaml"/>
    </common:BaseApp.RootVisual>

    <common:BaseApp.Resources>
        <converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
        <converters:BoolToVisibilityConverter x:Key="BoolToInvertedVisibilityConverter" IfTrue="Collapsed" IfFalse="Visible"/>
    </common:BaseApp.Resources>
</common:BaseApp>

UserControl XAML:

<UserControl 
    x:Name="FormatsControl"
    x:Class="xyz.Formats"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    d:DesignHeight="480" d:DesignWidth="480">

    <ItemsControl Background="Transparent" ItemsSource="{Binding ElementName=FormatsControl, Path=FormatAvailabilities}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="{Binding ElementName=FormatsControl, Path=Orientation}"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <TextBlock Text="{Binding BindsDirectlyToSource=True}" Margin="0,0,10,0" Visibility="{Binding ElementName=FormatsControl, Path=FullText, Converter={StaticResource BoolToVisibilityConverter}}"/>
                    <TextBlock Text="{Binding Description}" Margin="0,0,10,0" Visibility="{Binding ElementName=FormatsControl, Path=FullText, Converter={StaticResource BoolToInvertedVisibilityConverter}}"/>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</UserControl>

UserControl CS:

namespace xyz
{
    public partial class Formats : UserControl
    {
        public static readonly DependencyProperty FormatAvailabilitiesDependencyProperty = DependencyProperty.Register("FormatAvailabilities", typeof(FormatAvailability[]), typeof(Formats), null);
        public static readonly DependencyProperty OrientationDependencyProperty = DependencyProperty.Register("Orientation", typeof(Orientation), typeof(Formats), new PropertyMetadata(Orientation.Horizontal));
        public static readonly DependencyProperty FullTextDependencyProperty = DependencyProperty.Register("FullText", typeof(bool), typeof(Formats), null);

        public FormatAvailability[] FormatAvailabilities
        {
            get { return (FormatAvailability[])base.GetValue(Formats.FormatAvailabilitiesDependencyProperty); }
            set { base.SetValue(Formats.FormatAvailabilitiesDependencyProperty, value); }
        }

        public Orientation Orientation
        {
            get { return (Orientation)base.GetValue(Formats.OrientationDependencyProperty); }
            set { base.SetValue(Formats.OrientationDependencyProperty, value); }
        }

        public bool FullText
        {
            get { return (bool)base.GetValue(Formats.FullTextDependencyProperty); }
            set { base.SetValue(Formats.FullTextDependencyProperty, value); }
        }

        public Formats()
        {
            InitializeComponent();
        }
    }
}

I must be over looking something...thanks!

2
  • 1
    I assume you're defining the resources BoolToVisibilityConverter and BoolToInvertedVisibilityConverter in App.xaml or similar? It might help to update the question with this detail. Commented Mar 20, 2011 at 19:33
  • Your assumption is correct - updated my question to include that. Commented Mar 20, 2011 at 19:55

3 Answers 3

1

There is an issue with naming UserControls in Silverlight 3 as described by this blog post, which is also present in the Windows Phone 7 version of Silverlight. Effectively, if you give the UserControl a name in the XAML where it is used (i.e. it's parent), then that overrides the name given in the UserControl's own XAML file.

Sign up to request clarification or add additional context in comments.

3 Comments

Hmm that makes sense I suppose. Does that mean there's no way to make it work as I've posted?
@Josh - Actually it appears this is probably another issue, as a quick test showed that it does in fact work (regardless of what the documentation says). I updated my answer as such.
I've ran into this one before - so annoying.
1

I ran into a similar problem, instead of binding to the elementname I changed the binding to this

Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}

And that works just fine.

Comments

-1

Looks like you are missing the OnPropertyChanged handler.

Here is one of my dependency properties. Note the changed handler.

public ObservableCollection<ObjWithDesc> ItemsSource
{
    get 
    {
        return (ObservableCollection<ObjWithDesc>)GetValue(ItemsSourceProperty); 
    }
    set
    {
        SetValue(ItemsSourceProperty, value);
    }
}

public static readonly DependencyProperty ItemsSourceProperty =
    DependencyProperty.Register(
        "ItemsSource",
        typeof(ObservableCollection<ObjWithDesc>),
        typeof(HorizontalListBox),
        new PropertyMetadata(OnItemsSourcePropertyChanged)
    );

static void OnItemsSourcePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    ((HorizontalListBox) obj).OnItemsSourcePropertyChanged(e);
}

private void OnItemsSourcePropertyChanged(DependencyPropertyChangedEventArgs e)
{
    ObservableCollection<ObjWithDesc> objWithDescList = (ObservableCollection<ObjWithDesc>)e.NewValue;

    MainListBox.ItemsSource = objWithDescList;
}

3 Comments

The PropertyMetaData including the PropertyChangedHandler are optional. I'm not doing anything special with the value so there's no need to do anything in the PropertyChanged event. This is a direct and straightforward binding.
Worth a try though to see if it fixes the problem? It sounds like your dependency properties do not work when something changes - this should fix that.
I did hook up the event and I can see that the property is indeed changing. In fact, I copied the Visibility property as-is from the TextBlock to the ItemsControl and it works correctly there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.