Home > OS >  WPF Bind color to ellipse and update it automatically
WPF Bind color to ellipse and update it automatically

Time:12-08

I have this Ellipse with a RadialGradientBrush, where the colors are bind to the colors Light and Dark:

<Grid x:Name="gridEllipse">
  <Ellipse x:Name="ellipseMPCenter">
    <Ellipse.Fill>
      <RadialGradientBrush GradientOrigin="50,50" Center="50,50" Radius="1">
        <RadialGradientBrush.GradientStops>
          <GradientStop Color="{Binding Light}" Offset="0"/>
          <GradientStop Color="{Binding Dark}" Offset="1"/>
        </RadialGradientBrush.GradientStops>
      </RadialGradientBrush>
    </Ellipse.Fill>
  </Ellipse>
</Grid>

This is my code:

    public class UserControlLED : UserControl, INotifyPropertyChanged
    {
        private readonly Color colorGreenLight = Color.FromRgb(61, 214, 0);
        private readonly Color colorGreenDark = Color.FromRgb(10, 92, 1);
        private readonly Color colorRedLight = Color.FromRgb(235, 0, 0);
        private readonly Color colorRedDark = Color.FromRgb(130, 0, 0);

        private Color light;

        public Color Light
        {
            get
            {
                return light;
            }

            set
            {
                light = value;
                OnPropertyChanged(nameof(Light));
            }
        }

        private Color dark;

        public Color Dark
        {
            get
            {
                return dark;
            }

            set
            {
                dark = value;
                OnPropertyChanged(nameof(Dark));
            }
        }


        public UserControlLED()
        {
            InitializeComponent();

            Light = colorGreenLight;
            Dark = colorGreenDark;

            gridEllipse.DataContext = this;
        }

        private async void BtStartClicked(object sender, RoutedEventArgs args)
        {
            Light = colorRedLight;
            Dark = colorRedDark;
        }

        public event EventHandler<PropertyChangedEventArgs> PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

With this code, the Ellipse is colored green, even if I press the button. When I set the DataContext in the button click event again, nothing happens. Or do I need to put this in the OnPropertyChanged method? But this still does not work.

Where and when do I need to set the DataContext?

CodePudding user response:

Fix the Center property of the RadialGradientBrush and use RelativeSource Bindings:

<Ellipse.Fill>
    <RadialGradientBrush Center="0.5,0.5">
        <RadialGradientBrush.GradientStops>
            <GradientStop
                Color="{Binding Light,
                    RelativeSource={RelativeSource AncestorType=UserControl}}"
                Offset="0"/>
            <GradientStop
                Color="{Binding Dark,
                    RelativeSource={RelativeSource AncestorType=UserControl}}"
                Offset="1"/>
        </RadialGradientBrush.GradientStops>
    </RadialGradientBrush>
</Ellipse.Fill>

Do not implement INotifyPropertyChanged, but declare the properties as dependency properties:

public static readonly DependencyProperty LightProperty =
    DependencyProperty.Register(
        nameof(Light), typeof(Color), typeof(UserControlLED),
        new PropertyMetadata(Colors.White));

public static readonly DependencyProperty DarkProperty =
    DependencyProperty.Register(
        nameof(Dark), typeof(Color), typeof(UserControlLED),
        new PropertyMetadata(Colors.Black));

public Color Light
{
    get { return (Color)GetValue(LightProperty); }
    set { SetValue(LightProperty, value); }
}

public Color Dark
{
    get { return (Color)GetValue(DarkProperty); }
    set { SetValue(DarkProperty, value); }
}

Do not explicitly set the DataContext, because that would break the standard binding mechanism when you bind the control's properties like

<local:UserControlLED Light="{Binding SomeColor}" .../>
  • Related