0

I am using observable collection and dataTemplates to create generic panels, I have encountered an issue when my buttons colors (setted programaticly) do initializes, but once changed while running the color stays still.

Here is my Xaml code for the button:

<Button Grid.Column="0" Grid.Row="3" Background="{Binding Path=motionColor}" Command="{Binding Path=MotionPress}" Content="Motion" Height="51" Width="104" Style="{StaticResource MyButtonStyle}"/>

That's my DataTemplate:

<DataTemplate x:Key="GenericPanelTemplate"  DataType="local:GenericPanel">

And here's the relevant backend code in GenericPanel.cs:

motionColor:

public Brush motionColor { get; set; }

The function eventually the button execute (tested and running):

public void MotionButton_Click()
        {
                motionColor = setColor((byte)Value.ON);
        }
    private Brush setColor(byte value)
    {
        switch (value)
        {
            case (byte)Value.OFF:
                return Brushes.Red;
            case (byte)Value.ON:
                return Brushes.Green;
            case (byte)Value.PROGRESS:
                return Brushes.Yellow;
            default:
                return Brushes.Gray;
        }
    }

On start, the motionColor sets to be red, and the button does appear red, but when the value changed to Brushes.Green here it doesnt work anymore (debugging proves that the value changes correctly).

How do I make the button to check it's binded value and update the Background attribute?

If more code is needed please ask, I think these functions and Xaml lines are the only relevant ones.

Thanks for the help.

1
  • Your GenericPanel must implement INotifyPropertyChanged interface or motionColor must be a dependecy property. Otherwise your binding will never know that something has changed... Commented Jan 7, 2016 at 9:13

1 Answer 1

2

You must implement INotifyPropertyChanged (MSDN link) on the class containing the property, and notify the changes to your property.

Something like:

public GenericPanel : INotifyPropertyChanged
{
  private Brush _motionColor;
  public Brush motionColor { 
    get { return _motionColor; }; 
    set { 
      _motionColor = value; 
      OnPropertyChanged(); 
    }
  }

  /* ... the rest of your class ... */

  public event PropertyChangedEventHandler PropertyChanged;
  protected void OnPropertyChanged([CallerMemberName] string propertyName = null)  
  {        
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }
}

This all can be done automatically using Fody (specifically the PropertyChanged add-in) but if you only require it for this specific property, using Fody might be overkill

Update

Since the OP, as per the comments, seems to be using older versions of .NET and C#, here's the "more compatible" version:

public GenericPanel : INotifyPropertyChanged
{
  private Brush _motionColor;
  public Brush motionColor { 
    get { return _motionColor; }; 
    set { 
      _motionColor = value; 
      OnPropertyChanged("motionColor"); 
    }
  }

  /* ... the rest of your class ... */

  public event PropertyChangedEventHandler PropertyChanged;
  protected void OnPropertyChanged(string propertyName)  
  {
    var handle = PropertyChanged;
    if(handle != null) 
      handle(this, new PropertyChangedEventArgs(propertyName));
  }
}
Sign up to request clarification or add additional context in comments.

18 Comments

Hi what do you mean by [CallerMemberName]?
[CallerMemberName] is an attribute for a parameter that sets the caller member name on that parameter if it has a default value and no value is passed in. So in this case, it'll receive a string with "motionColor" as its content (since I'm not passing anything to OnPropertyChanged()). More info on the MSDN
Using it like that won't compile, I get "Error 2 The type or namespace name 'CallerMemberName' could not be found (are you missing a using directive or an assembly reference?) c:\users\dp27317\documents\visual studio 2010\Projects\GenericSoundMotion\GenericSoundMotion\GenericPanel.cs 310 43 GenericSoundMotion"
You need to add using System.Runtime.CompilerServices; on top of your file
If you are under .NET 4.5, just remove [CallerMemberName], and pass the parameter on the property setter: OnPropertyChanged(nameof(motionColor)); instead of OnPropertyChanged();. CallerMemberName is an addition to .NET 4.5 and won't work on earlier versions (well, you can actually make it work if using C# 5.0 or over, but that's outside the scope of this question)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.