wpf trouble using dependency properties in a UserControl

旧巷老猫 提交于 2019-12-01 03:52:09

Turns out that in the XAML for the user control, the binding was incorrectly specified.

Originally it was:

<Label Width="100" Height="30" Name="fieldValueLabel" Content="{Binding fieldValue}" />

But I had not specified the element to which fieldValue belongs. It should be (assuming my user control is named "LF":

<Label Width="100" Height="30" Name="fieldValueLabel" Content="{Binding ElementName=LF, Path=fieldValue}" />

If you want to bind to properties of the control, you should specify so in the binding. Bindings are evaluated relative to DataContext if their source isn't explicitly specified, so your binding doesn't bind to your control, but to the inherited context (which is likely missing the property you're binding to). What you need is:

<Label Width="100" Height="30" Name="fieldValueLabel"
       Content="{Binding Path=fieldValue, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DAS1.LabeledField}}}" />

You really don't need a dependency property on your user control, in fact you should strive to keep user controls without anything special in the code-behind, custom Controls should be used for that.

You should define your UserControl like this (without any code behind):

<UserControl x:Class="DAS1.LabeledField"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel Orientation="Horizontal">
        <Label Width="100" Height="30" Name="fieldNameLabel" Content="{Binding fieldName}" />
        <Label Width="100" Height="30" Name="fieldValueLabel" Content="{Binding field}" />
</StackPanel>

Then, make sure your business object implements INotifyPropertyChanged, because you cannot update from your business object efficiently without modifying it at least this much. The fieldName is just an example how you could bind the display name on the label automatically to a property on your business object.

Then, simply make sure the DataContext of your UserControl is your business object.

How will this work? The Label.Content property is a DependencyProperty and will support binding itself. Your business object implements INotifyPropertyChanged and thus supports updates to binding - without it, the binding system does not get notified when your field's value changes, regardless if you bound it to a DependencyProperty on one end.

And if you want to reuse this user control elsewhere, simply place a desired instance of your business object to the DataContext of the desired LabeledField control. The binding will hook up itself from the DataContext.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!