WPF 将数据绑定传递给用户控件

4
我创建了一个简单的UserControl,其中包含一个Value属性:
public partial class Label : UserControl
{
    public Label()
    {            
        InitializeComponent();
        DataContext = this;
    }

    public object Value
    {
        get { return GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(object), typeof(Label), new PropertyMetadata(""));
}

我正在使用以下这段XAML代码:

<Border BorderBrush="#A0A0A0" BorderThickness="1, 1, 0, 0" CornerRadius="1">
    <Border BorderBrush="#000000" BorderThickness="0, 0, 1, 1" CornerRadius="1">
        <Border.Background>
            <LinearGradientBrush StartPoint="0.5, 0" EndPoint="0.5, 1">
                <GradientStop Color="#FFFFFF" Offset="0.0" />
                <GradientStop Color="#E0E0E0" Offset="1.0" />
            </LinearGradientBrush>
        </Border.Background>
        <TextBlock Width="100" FontWeight="SemiBold" Padding="2" Text="{Binding Value}" />
    </Border>
</Border>

当我像这样明确设置值时,这个方法有效:

<uc:Label Value="Name" />

但是出于某些原因,当我尝试使用绑定时它却不起作用:
<ItemsControl ItemsSource="{Binding InfoDetran}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <!-- Doesn't work -->
                <uc:Label Value="{Binding Label}" />
                <!-- But this works -->
                <TextBox Text="{Binding Label}" />
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

我的用户控件的Value属性没有被更新,我得到了一个绑定错误:BindingExpression path error: 'Label' property not found on 'object' ''Label' (Name='')'. BindingExpression:Path=Label; DataItem='Label' (Name=''); target element is 'Label' (Name=''); target property is 'Value' (type 'Object') 这个object是在寻找它上面的属性,我做错了什么?

你的项目类型是什么(在“InfoDetran”中)?它们有“Label”属性吗? - molnarm
文本框工作正常吗? - aggietech
@aggietech 是的,标签的值在文本框上显示得很好。 - Danicco
1
将您的“Value”“DependencyProperty”类型更改为字符串而不是对象,看看是否有效。可能只是不匹配。 - Frank J
1
尝试不要将DataContext设置为此...它应该从父级继承。请参阅我的帖子。 - aggietech
显示剩余2条评论
2个回答

5

DataContext 是从父级继承的,这将覆盖您手动设置的内容。

您可以通过更改 XAML 将内容的 DataContext 绑定到控件本身来解决此问题,然后绑定将继续工作,因为继承的上下文始终是 UserControl 本身:

<UserControl ...
             x:Name="Root">
    <Border DataContext="{Binding ElementName=Root}"  BorderBrush="#A0A0A0" BorderThickness="1, 1, 0, 0" CornerRadius="1">
        <Border BorderBrush="#000000" BorderThickness="0, 0, 1, 1" CornerRadius="1">
            <Border.Background>
                <LinearGradientBrush StartPoint="0.5, 0" EndPoint="0.5, 1">
                    <GradientStop Color="#FFFFFF" Offset="0.0" />
                    <GradientStop Color="#E0E0E0" Offset="1.0" />
                </LinearGradientBrush>
            </Border.Background>
            <TextBlock Width="100" FontWeight="SemiBold" Padding="2" Text="{Binding Value}" />
        </Border>
    </Border>
</UserControl>

注意,我已经将控件命名为x:Name="Root"并将Border上下文绑定为DataContext="{Binding ElementName=Root}"
您可以从代码中删除DataContext = this

1
问题可能出在DP上吗? 如果您将标签重命名为其他名称,是否会解决问题? 此外,您可能无需覆盖数据上下文...它应该从其父控件继承,因为您正在将父属性绑定到它。
public partial class CustomLabel : UserControl
{
    public CustomLabel ()
    {            
        InitializeComponent();
    }

    public string Value
    {
        get { return (string)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(string), typeof(CustomLabel), new PropertyMetadata(""));
}

如果我从UserControl中删除DataContext = this;这一行,那么显式值也将停止工作。根据我的阅读,我应该指定属性来自哪个DataContext,并且我可以使用控件本身或每个绑定上的RelativeSource(在我看来会使XAML更糟)。我尝试重命名Label,但它没有起作用。 - Danicco
1
<TextBlock Width="100" FontWeight="SemiBold" Padding="2" Text="{Binding Value, RelativeSource={RelativeSource TemplatedParent}}" /> 将会修复你在 UserControl XAML 中的问题。 - Frank J
好的发现 @FrankJ - 我没有注意到 XAML 的那一部分。 - aggietech
@Daniichi,将所有这些更改结合起来(在代码后台中删除DataContext,在UserControl中将属性类型和绑定更改为TemplatedParent),现在可以工作了吗? - Frank J
@FrankJ 不,删除DataContext行不会绑定任何值,即使添加了RelativeSource行也是如此。我在集合外进行了测试,使用显式字符串,但都没有起作用。 - Danicco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接