0

I have a custom class which i want to bind to a dependency property. So that it updates the UI when it is changed. However it doesn´t work the way i programmed it. Can anyone tell me what I am doing wrong?

Here are some code snippets:

The UserControl XAML:

<UserControl x:Class="HexButton.HexButtonControl"
         .../>
<Canvas x:Name="LayoutRoot" MouseLeftButtonDown="LayoutRoot_MouseLeftButtonDown">
    <Polygon .../>
    <Rectangle
             Name="R_Unit"
             Height="70"
             Width="48"                 
             Canvas.Left="28"
             Canvas.Top="10"
     />
    <Label Name="L_UnitCount"
        ...
        Foreground="{Binding Path=LabelColor}"
        Canvas.Left="80" 
        Canvas.Top="31"/>        
</Canvas>
</UserControl>

UserControl C#

    {
    //....
    #region Move

    /// <summary>
    /// Gets or sets if the unit can move on this hexagon
    /// </summary>
    public bool Move
    {
        get { return (bool)GetValue(MoveProperty); }
        set
        {
            SetValue(MoveProperty, value);
            MoveChanged();
        }
    }

    /// <summary>
    /// Identified the move dependency property
    /// </summary>
    public static readonly DependencyProperty MoveProperty =
        DependencyProperty.Register("Move", typeof(bool),
          typeof(HexButtonControl), new PropertyMetadata(false));

    #endregion

    #region Unit

    /// <summary>
    /// Gets or sets the LabelText which is displayed next to the (unit-)rectangle
    /// </summary>
    public Unit AssinedUnit
    {
        get { return (Unit)GetValue(AssignedUnitProperty); }
        set
        {
            SetValue(AssignedUnitProperty, value);
            UnitChanged();
        }
    }

    /// <summary>
    /// Identified the LabelText dependency property
    /// </summary>
    public static readonly DependencyProperty AssignedUnitProperty =
        DependencyProperty.Register("AssignedUnit", typeof(Unit),
          typeof(HexButtonControl), new PropertyMetadata(new Unit()));

    #endregion   

    #endregion

    public HexButtonControl()
    {
        InitializeComponent();
        LayoutRoot.DataContext = this;
        Hexagon.Stroke = new SolidColorBrush(Colors.ForestGreen);
        //UnitChanged();
    }

private void MoveChanged()
    {
        if (Move)
        {
            OldBorderBrush = Hexagon.Stroke;
            Hexagon.Stroke = new SolidColorBrush(Colors.Yellow);
        }
        else
        {
            Hexagon.Stroke = OldBorderBrush;
        }
    }

    private void UnitChanged()
    {
        string unitPic = @"C:\Users\Public\Pictures\Sample Pictures\Test\";            
        L_UnitCount.Content = AssinedUnit.UnitCount.ToString();

        switch (AssinedUnit.UnitKind)
        {
            case UnitType.Ranger: unitPic+="A-";
                break;
            case UnitType.Meele: unitPic+="F-";
                break;
            case UnitType.Cavalry: unitPic+="R-";
                break;
            default: break;
        }

        switch (AssinedUnit.Strength)
        {
            case UnitStrength.Light: unitPic += "light.png";
                break;
            case UnitStrength.Medium: unitPic += "medium.png";
                break;
            case UnitStrength.Heavy: unitPic += "heavy.png";
                break;
            default: break;
        }

        R_Unit.Fill = new SolidColorBrush(Colors.Black);
        R_Unit.Fill = new ImageBrush(new BitmapImage(new Uri(unitPic)));

    }
//....
}

The model:

 public class HexModelObject
{
    private Unit _assignedUnit;
    public Unit AssignedUnit
    {
        get { return _assignedUnit; }
        set
        {
            _assignedUnit = value;
            OnPropertyChanged("Unit");
        }
    }
//...
        public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

The UnitClass:

public class Unit
{
    public UnitType UnitKind { get; set; }
    public UnitStrength Strength { get;  set; }
    public int UnitCount { get;  set; }

    public Unit() : this(UnitType.Ranger, UnitStrength.Light, 3) { }

    public Unit(UnitType type, UnitStrength strengt, int unitCount)
    {
        UnitKind = type;
        Strength = strengt;
        UnitCount = unitCount;
    }

}

public enum UnitType
{
    Meele,
    Ranger,
    Cavalry
}

public enum UnitStrength
{
    Light,
    Medium,
    Heavy
}

The Main Window:

        HexButtonControl hbc1 = new HexButtonControl();
        hbc1.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
        hbc1.VerticalAlignment = System.Windows.VerticalAlignment.Top;
        hbc1.Margin = new Thickness(left, top, 0, 0);

        HexModelObject hmo1 = new HexModelObject()
        {                
            LabelColor = new SolidColorBrush(Colors.Black),
            //RectangleBrush = new SolidColorBrush(Colors.Honeydew),
            HexBackground = new SolidColorBrush(Colors.LightBlue),
            Move = false,
            AssignedUnit = new Unit()
        };

        Binding b_move = new Binding("Move");
        b_move.Source = hmo1;
        b_move.Mode = BindingMode.TwoWay;
        hbc1.SetBinding(HexButtonControl.MoveProperty, b_move);

        Binding b_unit = new Binding("AssignedUnit");
        b_unit.Source = hmo1;
        b_unit.Mode = BindingMode.TwoWay;
        hbc1.SetBinding(HexButtonControl.AssignedUnitProperty, b_unit);

        hmo1.AssignedUnit.Strength = UnitStrength.Heavy;

        this.myGrid.Children.Add(hbc1);
    }

When I add the UnitChanged(); to the constructor of the UserCotrol it works once, so there is no Problem with missing imagefiles etc. When I dont add it, the rectangle and the label are blank.

What am I doing wrong? It works for all other dependency properties I added, but they are all basic types (like int, string, Brush, etc...)

Thoms
  • 87
  • 8
  • You must not call anything else than `SetValue` in the setter method of the CLR wrapper of a dependency property, e.g. don't call `UnitChanged()` or `MoveChanged()` there. The reason is that the property setter may be bypassed by WPF. Instead, register a `PropertyChangedCallback` with PropertyMetadata passed to the `Register` method. – Clemens Aug 09 '16 at 13:31
  • Thanks, worked perfectly. Can you tell me why the setter **may** be bypassed by WPF? – Thoms Aug 10 '16 at 13:48

0 Answers0