1

要素のコレクションを持つ単純なコントロールがあります。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 を見ると、どのバインディングが存在するかは明らかではありません。(回避策のコードについては私の回答を参照してください)

4

2 に答える 2