Share via

Toggle Button Color Bound Property Not Concistant

Marc Jeeves 386 Reputation points
2020-04-09T19:37:23.907+00:00

Can't get my color property's bind logic right. I get odd color behavior and occasionally the toggle switch switches back on its own.

Can anybody help

Thanks

Madaxe

<UserControl x:Class="WpfApp5.ToggleButtonUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApp5"
             mc:Ignorable="d" 
             d:DesignHeight="120" d:DesignWidth="240">

    <Grid>
        <Viewbox>
            <Grid Height="120" Width="240" Margin="0,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top">
                <Rectangle Name="Rec_Back" 
                           MouseLeftButtonDown="Rec_Back_MouseLeftButtonDown" 
                           Fill="{Binding _CurrentColor,FallbackValue=OrangeRed}"
                           Height="115" Width="235" 
                           RadiusY="60" RadiusX="60" 
                           Margin="2.5,2.5,2.5,2.5" 
                           HorizontalAlignment="Left" VerticalAlignment="Top"/>
                <Ellipse Name="Eli_Slider" 
                         MouseLeftButtonDown="Eli_Slider_MouseLeftButtonDown"
                         Fill="{Binding ButtonColor,FallbackValue=White}"
                         Margin="5, 5, 5, 5"
                         Height="110" Width="110" 
                         HorizontalAlignment="Left" VerticalAlignment="Top" />
            </Grid>
        </Viewbox>
    </Grid>
</UserControl>


using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace WpfApp5
{
    public partial class ToggleButtonUserControl : UserControl
    {
        public bool IsToggled
        {
            get { return (bool)GetValue(IsToggledProperty);}
            set { SetValue(IsToggledProperty, value);}
        }

        public static readonly DependencyProperty IsToggledProperty =
            DependencyProperty.Register("IsToggled", typeof(bool), typeof(ToggleButtonUserControl), 
                new PropertyMetadata(false, new PropertyChangedCallback(ChangeIsToggled)));

        private static void ChangeIsToggled(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if ((bool)e.NewValue == false)
            {
                (d as ToggleButtonUserControl).Eli_Slider.Margin = (d as ToggleButtonUserControl)._LeftThickness;
                (d as ToggleButtonUserControl).Rec_Back.Fill  = (d as ToggleButtonUserControl).SlideColorOff;
                (d as ToggleButtonUserControl)._CurrentColor = (d as ToggleButtonUserControl).SlideColorOff;
            }
            else
            {
                (d as ToggleButtonUserControl).Eli_Slider.Margin = (d as ToggleButtonUserControl)._RightThickness;
                (d as ToggleButtonUserControl).Rec_Back.Fill = (d as ToggleButtonUserControl).SlideColorOn;
                (d as ToggleButtonUserControl)._CurrentColor = (d as ToggleButtonUserControl).SlideColorOn;
            }
        }


        public SolidColorBrush ButtonColor
        {
            get { return (SolidColorBrush)GetValue(ButtonColorProperty); }
            set { SetValue(ButtonColorProperty, value); }
        }
        public static readonly DependencyProperty ButtonColorProperty =
            DependencyProperty.Register("ButtonColor", typeof(SolidColorBrush), typeof(ToggleButtonUserControl), 
                new PropertyMetadata(Brushes.White, new PropertyChangedCallback(ChangeButtonColor)));
        private static void ChangeButtonColor(DependencyObject d, DependencyPropertyChangedEventArgs e) { }

        public SolidColorBrush SlideColorOn
        {
            get { return (SolidColorBrush)GetValue(SlideColorOnProperty); }
            set { SetValue(SlideColorOnProperty, value); }
        }
        public static readonly DependencyProperty SlideColorOnProperty =
            DependencyProperty.Register("SlideColorOn", typeof(SolidColorBrush), typeof(ToggleButtonUserControl), 
                new PropertyMetadata(Brushes.Green, new PropertyChangedCallback(ChangeSlideColorOn)));
        private static void ChangeSlideColorOn(DependencyObject d, DependencyPropertyChangedEventArgs e) { }

        public SolidColorBrush SlideColorOff
        {
            get { return (SolidColorBrush)GetValue(SlideColorOffProperty); }
            set { SetValue(SlideColorOffProperty, value); }
        }
        public static readonly DependencyProperty SlideColorOffProperty =
            DependencyProperty.Register("SlideColorOff", typeof(SolidColorBrush), typeof(ToggleButtonUserControl), 
                new PropertyMetadata(Brushes.OrangeRed, new PropertyChangedCallback(ChangeSlideColorOff)));
        private static void ChangeSlideColorOff(DependencyObject d, DependencyPropertyChangedEventArgs e) { }



        private Thickness _LeftThickness = new Thickness(5, 5, 5, 5);
        private Thickness _RightThickness = new Thickness(125, 5, 5, 5);
        private SolidColorBrush _CurrentColor = null;



        public ToggleButtonUserControl()
        {
            InitializeComponent();
            Eli_Slider.DataContext = this;
            Rec_Back.DataContext = this;
            this._CurrentColor = this.SlideColorOff;
        }

        private void Eli_Slider_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.IsToggled = (this.IsToggled) ? false : true;
        }

        private void Rec_Back_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.IsToggled = (this.IsToggled) ? false : true;
        }
    }
}
Developer technologies | Windows Presentation Foundation
0 comments No comments

Answer accepted by question author

Peter Fleischer (former MVP) 19,351 Reputation points
2020-04-10T07:29:55.44+00:00

Hi, you can simplify the code like this:

XAML:

<UserControl x:Class="WpfControlLibrary1.Window25UC3"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfControlLibrary1"
             mc:Ignorable="d" 
             d:DesignHeight="120" d:DesignWidth="240" 
             PreviewMouseLeftButtonDown="UserControl_PreviewMouseLeftButtonDown">
  <Grid>
    <Viewbox>
      <Grid x:Name="grd">
        <Rectangle Fill="{Binding CurrentColor, FallbackValue=OrangeRed}"
               Height="115"
               Width="235"
               RadiusY="60"
               RadiusX="60"       
               Margin="2.5 2.5 2.5 2.5"/>
        <Ellipse Fill="{Binding ButtonColor, FallbackValue=White}"     
             Margin="5 5 5 5"        
             Height="110" 
             Width="110"  
             HorizontalAlignment="{Binding CurrentPosition, FallbackValue=Left}"/>
      </Grid>
    </Viewbox>
  </Grid>
</UserControl>

Code:

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace WpfControlLibrary1
{
  /// <summary>
  /// Interaction logic for Window25UC3.xaml
  /// </summary>
  public partial class Window25UC3 : UserControl,  INotifyPropertyChanged
  {
    public Window25UC3()
    {
      InitializeComponent();
      this.grd.DataContext = this;
    }
    private void UserControl_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) => IsToggled = !IsToggled;

    public bool IsToggled
    {
      get { return (bool)GetValue(IsToggledProperty); }
      set { SetValue(IsToggledProperty, value); }
    }

    public static readonly DependencyProperty IsToggledProperty =
        DependencyProperty.Register("IsToggled", typeof(bool), typeof(Window25UC3),
            new PropertyMetadata(false, new PropertyChangedCallback(ChangeIsToggled)));

    private static void ChangeIsToggled(DependencyObject d, DependencyPropertyChangedEventArgs e) => 
      (d as Window25UC3).SetDesign((bool)e.NewValue);

    public SolidColorBrush ButtonColor
    {
      get { return (SolidColorBrush)GetValue(ButtonColorProperty); }
      set { SetValue(ButtonColorProperty, value); }
    }
    public static readonly DependencyProperty ButtonColorProperty =
        DependencyProperty.Register("ButtonColor", typeof(SolidColorBrush), typeof(Window25UC2),
            new PropertyMetadata(Brushes.White));

    public SolidColorBrush SlideColorOn
    {
      get { return (SolidColorBrush)GetValue(SlideColorOnProperty); }
      set { SetValue(SlideColorOnProperty, value); }
    }
    public static readonly DependencyProperty SlideColorOnProperty =
        DependencyProperty.Register("SlideColorOn", typeof(SolidColorBrush), typeof(Window25UC2),
            new PropertyMetadata(Brushes.Green));

    public SolidColorBrush SlideColorOff
    {
      get { return (SolidColorBrush)GetValue(SlideColorOffProperty); }
      set { SetValue(SlideColorOffProperty, value); }
    }
    public static readonly DependencyProperty SlideColorOffProperty =
        DependencyProperty.Register("SlideColorOff", typeof(SolidColorBrush), typeof(Window25UC2),
            new PropertyMetadata(Brushes.OrangeRed));

    private void ToggleAction()
    {
      IsToggled = !IsToggled;
      SetDesign(IsToggled);
    }

    public Brush CurrentColor { get; set; } = Brushes.OrangeRed;

    public HorizontalAlignment CurrentPosition { get; set; } = HorizontalAlignment.Left;

    private void SetDesign(bool toogleValue)
    {
      CurrentColor = (toogleValue) ? this.SlideColorOn : this.SlideColorOff;
      CurrentPosition = (toogleValue) ? HorizontalAlignment.Right : HorizontalAlignment.Left;
      OnPropChanged(nameof(CurrentColor));
      OnPropChanged(nameof(CurrentPosition));
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropChanged([CallerMemberName] string propertyName = "") =>
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }
}

Was this answer helpful?

0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Marc Jeeves 386 Reputation points
    2020-04-10T16:44:44.11+00:00

    Thank you so much lots to learn.

    Was this answer helpful?

    0 comments No comments

  2. Peter Fleischer (former MVP) 19,351 Reputation points
    2020-04-09T19:49:21.273+00:00

    Hi, you use _CurrentColor for binding. WPF supports only property binding. You must change field _CurrentColor to property.

    private Thickness _LeftThickness = new Thickness(5, 5, 5, 5);
    private Thickness _RightThickness = new Thickness(125, 5, 5, 5);
    **public SolidColorBrush _CurrentColor { get; set; } = null;**
    

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.