Home > Software engineering >  WPF databinding to structured data property
WPF databinding to structured data property

Time:04-29

How can I register a child property of the data context as dependency property?

In the following case, I want to register the two properties "EU" and "Simulate" as dependency properties of Analog Input. Those two properties are part of Scaling class which is a part of the Data Context AI Class. How can I do that?

At the XAML side:

<TextBlock Text="{Binding EU, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:AnalogInput}}}"
                                                       FontSize="11" FontFamily="Verdana" Foreground="Black" HorizontalAlignment="Center" VerticalAlignment="Center" />

The code behind:

public class AnalogInput : BaseUserDynamo
{
    public static readonly DependencyProperty EUProperty = DependencyProperty.Register("EU", typeof(float), typeof(Scaling));
    public static readonly DependencyProperty UnitProperty = DependencyProperty.Register("Unit", typeof(string), typeof(AnalogInput));
    public static readonly DependencyProperty SimulateProperty = DependencyProperty.Register("Simulate", typeof(bool), typeof(Scaling));
    public static readonly DependencyProperty ResolutionProperty = DependencyProperty.Register("Resolution", typeof(int), typeof(AnalogInput));

    static AnalogInput()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(AnalogInput), new FrameworkPropertyMetadata(typeof(AnalogInput)));
    }

    public AnalogInput()
    {
        try
        {
            AI myAI = new AI();
            DataContext = myAI;
            myAI.PropertyChanged  = MyObj_PropertyChanged;
      
        }
        catch (Exception)
        {
            throw;
        }

    }
}

The scaling is a part of the AI class.

internal class AI : PLCBaseObject
{
    private Scaling _ScaleIn;
    private string _Unit;
    private int _Resolution;

    public Scaling ScaleIn { get { return _ScaleIn; } set { if (value != _ScaleIn) { _ScaleIn = value; OnPropertyChanged(); } } }
    public string Unit { get { return _Unit; } set { if (value != _Unit) { _Unit = value; OnPropertyChanged(); } } }
    public int Resolution { get { return _Resolution; } set { if (value != _Resolution) { _Resolution = value; OnPropertyChanged(); } } }
}

The Scaling Class has a bunch of properties.

public class Scaling : PLCBaseObject
{
    private bool _Simulate;
    private float _EU;

    public bool Simulate { get { return _Simulate; } set { if (value != _Simulate) { _Simulate = value; OnPropertyChanged(); } } }
    public float EU { get { return _EU; } set { if (value != _EU) { _EU = value; OnPropertyChanged(); } } }

}

CodePudding user response:

either you use DependencyProperty SimulateProperty or _Simulate field. you can not mix both. The DependencyProperty is not synchronized with the _Simulate field.

// class Scaling 
public static readonly DependencyProperty SimulateProperty = DependencyProperty.Register(
        "Simulate", typeof(bool), typeof(Scaling), new PropertyMetadata(default(bool)));

public bool Simulate {
    get { return (bool) GetValue(SimulateProperty); }
    set { SetValue(SimulateProperty, value); }
}

if your datacontext shall be AI, the AI class must derive from DependencyObject. else AnalogInput can hold the DependencyProperty but then you must synchronize the values yourself (copy the value of Scaling.Simulate to SimulateProperty) so AnalogInput acts as wrapper.

// class AnalogInput
public static readonly DependencyProperty SimulateProperty = DependencyProperty.Register(
        "Simulate", typeof(bool), typeof(AnalogInput), new PropertyMetadata(default(bool)));

public bool Simulate {
    get { return (bool) GetValue(SimulateProperty); }
    set { SetValue(SimulateProperty, value); }
}
  • Related