Can anyone explain why the binding on TagObject
below code throws the following binding exception?
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Value; DataItem=null; target element is 'TagObject' (HashCode=37895910); target property is 'Value' (type 'String')
My suspicion is its because TagObject
itself isn't a subclass of FrameworkElement
so it doesn't have a data context itself and thus doesn't know how to resolve the XAML binding.
To test, I changed the base type of TagObject
to FrameworkElement
and sure enough, the binding error went away, but Value
still didn't change. My theory there is although the binding was now valid, TagObject
wasn't part of the Visual Tree, therefore it didn't inherit its DataContext
.
I also tried giving 'TextBlocka name, then specifying it as the
ElementNamein the binding, but that again threw a binding exception. In this case, my suspicion is that it can't find the named element because
TagObject` still is not part of the visual tree, even with the base-class change above.
For the record, I do know a solution would be to simply hide that object creation behind a ValueConverter to wrap it for me, but I'm wondering if there's a XAML-only solution to address that binding on TagObject
.
Here's the XAML:
<Window x:Class="Test.TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:test="clr-namespace:Test">
<Window.Resources>
<DataTemplate DataType="{x:Type test:DataObject}">
<TextBlock Text="{Binding Value}">
<TextBlock.Tag>
<test:TagObject Value="{Binding Value}" />
</TextBlock.Tag>
</TextBlock>
</DataTemplate>
</Window.Resources>
<ListBox x:Name="MainListBox" BorderThickness="0" />
</Window>
This doesn't work either...
<TextBlock x:Name="MyTextBlock" Text="Test">
<TextBlock.Tag>
<test:TargetObject Value="{Binding DataContext.Value, ElementName=MyTextBlock}" />
</TextBlock.Tag>
</TextBlock>
Here's the code:
using System.Windows;
using System.Collections.ObjectModel;
namespace Test
{
public partial class TestWindow : Window
{
public TestWindow()
{
InitializeComponent();
var sourceItems = new ObservableCollection<DataObject>();
for(int i = 1; i <= 10; i++)
sourceItems.Add(new DataObject() { Value = "Item " + i});
MainListBox.ItemsSource = sourceItems;
}
}
public class DataObject : DependencyObject
{
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
"Value",
typeof(string),
typeof(DataObject),
new UIPropertyMetadata(null));
public string Value
{
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
}
public class TagObject : DependencyObject
{
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
"Value",
typeof(string),
typeof(TagObject),
new UIPropertyMetadata(null));
public string Value
{
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
}
}