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。绑定表达式:路径=文本;数据项=空;目标元素是'Bar'(HashCode=26568931);目标属性是“值”(类型“字符串”)

任何建议如何让它工作?

我目前的解决方法是在代码中定义绑定,但这是更多代码,并且查看 xaml 并不明显存在哪些绑定。(请参阅我的解决方法代码的答案)

4

2 回答 2

1

不知道这是否有帮助,但是

[ContentProperty("Bars")]
public class FooControl : Control
{
   private ObservableCollection<object> _bars = new ObservableCollection<object>();
   public ObservableCollection<object> Bars { get { return _bars; } }
}

xml

  <this:FooControl>
        <this:Bar Value="directly set"/>
        <this:Bar Value="{Binding Source=from_binding_source}"/>
        <TextBlock Text="{Binding}"/>
        <TextBlock Text="{Binding Text, ElementName=SomeTextBlock}"/>
    </this:FooControl>

你得到你想要的结果

在此处输入图像描述

于 2013-07-31T10:48:00.790 回答
0

到目前为止我的解决方法

    <this:Bar x:Name="bar3" />
    <this:Bar x:Name="bar4" />

void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    var bar3 = (DependencyObject)FindName("bar3");
    BindingOperations.SetBinding(bar3, Bar.ValueProperty, new Binding("DataContext") { Source = this });

    var bar4 = (DependencyObject)FindName("bar4");
    BindingOperations.SetBinding(bar4, Bar.ValueProperty, new Binding("Text") { Source = FindName("SomeTextBlock") });
}
于 2013-07-31T12:58:34.520 回答