views:

77

answers:

2

I have the following XAML:

<UserControl.Resources>

<DataTemplate x:Key="ExpanderTemplate">
    <Grid>
        <Rectangle Stroke="Black" StrokeThickness="1" Width="10" Height="10" Fill="White" />
        <Rectangle Stroke="Black" StrokeThickness="1" Width="6" Height="1" Fill="Black" />
        <Rectangle Stroke="Black" StrokeThickness="3" Width="2" Height="6" Fill="Black" />
    </Grid>
</DataTemplate>

<DataTemplate x:Key="CollapserTemplate">
    <Grid>
        <Rectangle Stroke="Black" StrokeThickness="1" Width="10" Height="10" Fill="White" />
        <Rectangle Stroke="Black" StrokeThickness="1" Width="6" Height="1" Fill="Black" />
    </Grid>
</DataTemplate>

</UserControl.Resources>

<Grid>
<StackPanel Orientation="Horizontal">
    <TextBlock Text="{Binding Path=Name}" />
    <Grid>
        <ContentPresenter x:Name="ExpanderPresenter" ContentTemplate="{StaticResource ExpanderTemplate}" Visibility="{Binding ExpanderVisibility}" />
        <ContentPresenter x:Name="CollapserPresenter" ContentTemplate="{StaticResource CollapserTemplate}" Visibility="{Binding CollapserVisibility}" />
    </Grid>
</StackPanel>
</Grid>

As you can see, it's essentially a textblock with its contents bound to a name, and two contentpresenters which have their visibility bound to a couple of Visibility objects on the source class. The source class looks like this:

public class MyViewModel
{
public string Name { get; set; }

public Visibility CollapserVisibility
{
    get
    {
        if (IsExpandable && IsExpanded)
        {
            return Visibility.Visible;
        }
        else
        {
            return Visibility.Collapsed;
        }
    }
}

public Visibility ExpanderVisibility
{
    get
    {
        if (IsExpandable && !IsExpanded)
        {
            return Visibility.Visible;
        }
        else
        {
            return Visibility.Collapsed;
        }
    }
}

public bool IsExpanded { get; set; }
public bool IsExpandable { get; set; }
}

The problem I am experiencing is that the bindings with the Visibility objects never even happen. The binding with the Name string does happen, and I have verified that (both visually and by expanding out and putting a breakpoint in the getter), but when I put breakpoints in the getters of the CollapserVisibility and ExpanderVisibility objects, those breakpoints never even get hit. Why is this? I'm also not getting any binding errors in the output window of Visual Studio, which further confuses me, so it acts as if the binding was set up correctly.

Am I not allowed to bind the Visibility property of a ContentPresenter? I also tried moving the Visibility bindings to be on the "Grid" objects in the data templates (in the XAML), but to no avail...it didn't work.

What's wrong with my binding? Thanks for any help.

+1  A: 

Are you ever putting any content into the contentpresenter? It might not be showing anything because there's nothing to show. The datatemplate dictates how the data should look, but you need to actually put data into it first.

Aside from that, the bindings look like they should work for the initial values, but they won't update if the IsExpandable or IsExpanded properties change.

You'd probably be a lot better off using a MultiDataTrigger to control the visibility.

mdm20
Hm I was under the impression that I could define the ContentTemplate and get the UI in those templates to display even without specifically defining the Content property. Anyways, I tried taking the Grid objects out of the data templates and just putting them raw in the UserControl.Resources, then I defined the Content property to use them as static resources, and it works. So thanks for the suggestions.As for the updating of the visibilities, yeah I know. I will implement INotifyPropertyChanged on these things, I was just trying to get the binding to work in the first place.
David
+1  A: 

If you change the ContentPresenter to a ContentControl it works (in that it binds to your visibility properties - I'm ignoring the fact that your VM doesn't notify of changes):

<ContentControl x:Name="ExpanderPresenter" ContentTemplate="{StaticResource ExpanderTemplate}" Visibility="{Binding ExpanderVisibility}" />
<ContentControl x:Name="CollapserPresenter" ContentTemplate="{StaticResource CollapserTemplate}" Visibility="{Binding CollapserVisibility}" />

I really can't explain why this is, apart from the fact that ContentPresenter is supposed to be used within the template of a ContentControl. But, to me, it should still work. I think it would require some Reflector-based sleuthing to figure this one out.

HTH,
Kent

Kent Boogaart