要素のコレクションを持つ単純なコントロールがあります。xaml に要素を追加し、要素にバインドしたい。
ただし、xaml で Bar.Value にバインドすると、機能しません。最小限の例:
[ContentProperty("Bars")]
public class FooControl : Control
{
private ObservableCollection<IBar> _bars = new ObservableCollection<IBar>();
public ObservableCollection<IBar> Bars { get { return _bars; } }
}
public interface IBar
{
string Value { get; }
}
public class Bar : DependencyObject, IBar
{
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(string), typeof(Bar), new PropertyMetadata("<not set>"));
public string Value
{
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
}
<Window x:Class="WpfTestApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:this="clr-namespace:WpfTestApplication"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="200" Width="1000">
<Window.Resources>
<Style TargetType="this:FooControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="this:FooControl">
<ItemsControl ItemsSource="{Binding Bars, RelativeSource={RelativeSource TemplatedParent}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Window.DataContext>
<sys:String>from DataContext</sys:String>
</Window.DataContext>
<Grid>
<this:FooControl>
<this:Bar Value="directly set"/>
<this:Bar Value="{Binding Source=from_binding_source}"/>
<this:Bar Value="{Binding}"/>
<this:Bar Value="{Binding Text, ElementName=SomeTextBlock}"/>
</this:FooControl>
<TextBlock Text="from TextBox" Name="SomeTextBlock" Visibility="Collapsed"/>
</Grid>
</Window>
出力
directly set
from_binding_source
"<not set>"
"<not set>"
デバッグ出力
System.Windows.Data エラー: 2: ターゲット要素の管理 FrameworkElement または FrameworkContentElement が見つかりません。BindingExpression: パス = テキスト; DataItem=null; ターゲット要素は 'Bar' (HashCode=26568931) です。ターゲット プロパティは 'Value' (タイプ 'String') です
それを機能させる方法はありますか?
私の現在の回避策は、コードでバインディングを定義することですが、これはより多くのコードであり、xaml を見ると、どのバインディングが存在するかは明らかではありません。(回避策のコードについては私の回答を参照してください)