gregsdennis
gregsdennis

Reputation: 8428

WPF Binding and DataTemplate

I have run into a problem in my app and I can't get past it. I have created the following simple WPF app to illustrate the situation.

MainWindow.xaml:

<Window x:Class="GlobalDataTemplate.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:GlobalDataTemplate"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate DataType="{x:Type my:MyData}">
            <StackPanel Background="{Binding BgColor}">
                <TextBlock Text="{Binding Text}"/>
                <TextBlock Text="{Binding Number}"/>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <ItemsControl>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Columns="3" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <my:MyData x:Name="NW" Text="NW" Number="1" BgColor="#FFFF0000" />
        <my:MyData x:Name="N" Text="N"  Number="2" BgColor="#FF63FF00" />
        <my:MyData x:Name="NE" Text="NE" Number="3" BgColor="#FFFFCA00" />
        <my:MyData x:Name="W" Text="W" Number="4" BgColor="#FF0037FF" />
        <my:MyData x:Name="C" Text="C" Number="5" BgColor="#FF9E00FF" />
        <my:MyData x:Name="E" Text="E" Number="6" BgColor="#FF838383" />
        <my:MyData x:Name="SW" Text="SW" Number="7"
                   BgColor="{Binding ElementName=NW, Path=BgColor}" />
        <my:MyData x:Name="S" Text="S" Number="8"
                   BgColor="{Binding ElementName=N, Path=BgColor}" />
        <my:MyData x:Name="SE" Text="SE" Number="9"
                   BgColor="{Binding ElementName=NE, Path=BgColor}" />
    </ItemsControl>
</Window>

MyData.cs:

using System.Windows;
using System.Windows.Media;

namespace GlobalDataTemplate
{
    class MyData : DependencyObject
    {
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(MyData), new UIPropertyMetadata(null));

        public int Number
        {
            get { return (int)GetValue(NumberProperty); }
            set { SetValue(NumberProperty, value); }
        }
        public static readonly DependencyProperty NumberProperty =
            DependencyProperty.Register("Number", typeof(int), typeof(MyData), new UIPropertyMetadata(0));

        public Brush BgColor
        {
            get { return (Brush)GetValue(BgColorProperty); }
            set { SetValue(BgColorProperty, value); }
        }
        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BgColorProperty =
            DependencyProperty.Register("BgColor", typeof(Brush), typeof(MyData), new UIPropertyMetadata(null));
    }
}

From the XAML, you would expect to see a 3x3 grid with the same colors across the bottom as shows across the top. But none of the colors for the bottom row show at all (you see the white background of the window). How can I get the colors at the bottom to bind to the colors at the top properly?

I've also tried adding a property changed handler and setting a break point. The break point is never hit.

Thanks in advance.

Upvotes: 0

Views: 400

Answers (1)

user128300
user128300

Reputation:

When I run your code, I get this error message in the debug output:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=BgColor; DataItem=null; target element is 'MyData' (HashCode=65325907); target property is 'BgColor' (type 'Brush')

I.e. that means that WPF does not consider the MyData items as part of the logical tree. Therefore, derive MyData from Freezable, e.g.

class MyData : Freezable 
{
    protected override Freezable CreateInstanceCore()
    {
        throw new System.NotImplementedException();
    }

    ... put the dependency properties here ...

}

The "Cannot find governing FrameworkElement..." problem has to do with "inheritance contexts"; please find details here: http://blogs.msdn.com/b/nickkramer/archive/2006/08/18/705116.aspx .

Upvotes: 1

Related Questions