views:

627

answers:

1

I'm trying to adapt a soltuion for the WPF toolkit's calendar from http://msdn.microsoft.com/en-us/magazine/dd882520.aspx but I'm having problems getting a binding on the usercontrol to work. I've tried using FindAncestor and ElementName, but I just get a binding error.

I think it might have something to do with the tooltip and it's DataContext in the calendar. Has anyone else had this problem?

<UserControl x:Class="ChickenPing.MealCalendar"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:conv="clr-namespace:ChickenPing.Converters"
    xmlns:wpf="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
    xmlns:primitives="clr-namespace:Microsoft.Windows.Controls.Primitives;assembly=WPFToolkit"
    xmlns:vsm="clr-namespace:System.Windows;assembly=WPFToolkit"
    xmlns:loc="clr-namespace:ChickenPing"
    x:Name="root">
    <wpf:Calendar x:Name="calendar">
        <wpf:Calendar.Resources>
            <conv:IconConverter x:Key="IconConverter"/>
            <conv:MealCalendarConverter x:Key="MealCalendarConverter" />
            <!--LinearGradientBrush x:Key="MealBackgroundFill" StartPoint="0,0"  EndPoint="0,1">
                <GradientStop Color=""
            </LinearGradientBrush-->
        </wpf:Calendar.Resources>
        <wpf:Calendar.CalendarDayButtonStyle>
            <Style TargetType="primitives:CalendarDayButton">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="primitives:CalendarDayButton">
                            <Grid>
                                <!Grid.ToolTip>
                                    <ToolTip>
                                        <ToolTip.DataContext>
                                            <MultiBinding Converter="{StaticResource MealCalendarConverter}">
                                                <Binding Path="PlacementTarget.DataContext" RelativeSource="{x:Static RelativeSource.Self}"/>
                                                <Binding Path="Meals">
                                                    <Binding.RelativeSource>
                                                        <RelativeSource Mode="FindAncestor" AncestorType="{x:Type loc:MealCalendar}" />
                                                    </Binding.RelativeSource>
                                                </Binding>
                                            </MultiBinding>
                                        </ToolTip.DataContext>

The error is:

System.Windows.Data Warning: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='MyAssembly.MyControl', AncestorLevel='1''. BindingExpression:Path=ConversionCollection; DataItem=null; target element is 'ToolTip' (Name=''); target property is 'DataContext' (type 'Object')

And the declaration for the DependencyProperty:

public static readonly DependencyProperty MealsProperty = DependencyProperty.Register("Meals", typeof(Dictionary<DateTime, IEnumerable<PlannedMealGroup>>), typeof(MealCalendar), new UIPropertyMetadata(new Dictionary<DateTime, IEnumerable<PlannedMealGroup>>()));
public Dictionary<DateTime, IEnumerable<PlannedMealGroup>> Meals {
    get { return base.GetValue(MealsProperty) as Dictionary<DateTime, IEnumerable<PlannedMealGroup>>; }
    set { 
        base.SetValue(MealsProperty, value);
    }
}

There's another control I have where the same thing happens, so I think I may be missing something.

A: 

Is ConversionCollection a property on the 'MyControl' user control? If so, you need to set the DataContext for this user control to itself as the default value for this property is null.

public MyControl()
{
    DataContext = this;
}

Edit: I noticed in your declaration of the ConversionCollectionProperty dependency property you declared the name as "Meals" but the property is actually ConversionCollection. These names need to match in order for the dependency property to operate as expected.

public static readonly DependencyProperty ConversionCollectionProperty =
    DependencyProperty.Register(
        "ConversionCollection", 
        typeof(Dictionary<DateTime, IEnumerable<PlannedMealGroup>>), 
        typeof(MyControl), 
        new UIPropertyMetadata(new Dictionary<DateTime,
        IEnumerable<PlannedMealGroup>>()));

public Dictionary<DateTime, IEnumerable<PlannedMealGroup>> ConversionCollection 
{
    get 
    { 
        return base.GetValue(ConversionCollectionProperty) as Dictionary<DateTime, IEnumerable<PlannedMealGroup>>; 
    }
    set 
    { 
        base.SetValue(ConversionCollectionProperty, value);
    }
Richard C. McGuire
Yes it is. I've updated the post with more detail.
Echilon
Sorry, I really don't know why I changed the names. Updated the original with the actual names from the control.
Echilon