WPF - User control - Change value in setter

LudoTxx 116 Reputation points
2021-10-26T15:21:58.07+00:00

hello,

SO i have a user control with some properties, i use databindng in my program for change this properties :

Here a part of my user control :

            public static readonly DependencyProperty ArcAngleProperty =
    DependencyProperty.Register(nameof(ArcAngle), typeof(double), typeof(uc_CircularGaugeType1));


            public double ArcAngle
            {
                get { return (double)this.GetValue(ArcAngleProperty); }
                set { this.SetCurrentValue(ArcAngleProperty, value);
                }
            }


<ed:Arc Name="arc_value" ArcThickness="35"  ArcThicknessUnit="Pixel" EndAngle="{Binding ElementName=root, Path=ArcAngle}" Fill="{Binding ElementName=root, Path=BackGroundColor}" Stretch="None" Stroke="#00000000" StartAngle="225"  RenderTransformOrigin="0.5,0.5"/>

I use databinding in my main program like this :

ArcAngle="{Binding myValue}"

To here everything work good but i want to do is :

This ArcAngle is binded with value always between 0 and 100. I want remap this value to another. I use this funtion who work like a charm :

        public static double MappingScaleDouble(double miniBase, double MaxiBase, double miniFinal, double maxiFinal, double value)
        {
            return miniFinal + (value - miniBase) * (maxiFinal - miniFinal) / (MaxiBase - miniBase);
        }

So for example, if my user control is a 1/4 of circle (90°) gauge i will call :

MappingScaleDouble(0, 100, 0, 90, MyValue);

If MyValue is 50 (so 50%) my function return me 45. (50% of 90).

For a half of circle gauge (180°) : if MyValue is 50 my function return me 90. (50% of 180).

Is it possible to make this remap in my user control ?

Thanks in advance, I hope my ask is clear..

here what i have try without success (for an 90° gauge) :

        public double ArcAngle
        {
            get { return (double)this.GetValue(ArcAngleProperty); }
            set { this.SetCurrentValue(ArcAngleProperty, MappingScaleDouble(0,100,0,90, value));
            }
        }
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,670 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,234 questions
0 comments No comments
{count} votes

Accepted answer
  1. LudoTxx 116 Reputation points
    2021-11-03T15:26:15.227+00:00

    Thanks, your code help me, the part with metadata specially.

    Here my code now and its working :

            public double ArcAngle
            {
                get { return (double)this.GetValue(ArcAngleProperty); }
                set { this.SetValue(ArcAngleProperty, value); }
            }
            public static readonly DependencyProperty ArcAngleProperty =
        DependencyProperty.Register(nameof(ArcAngle), typeof(double), typeof(uc_CircularGaugeType2), new PropertyMetadata(ArcAngleChangedCallBack));
            private static void ArcAngleChangedCallBack(DependencyObject sender, DependencyPropertyChangedEventArgs e)
            {
                uc_CircularGaugeType2 uc = sender as uc_CircularGaugeType2;
                uc.arc_Progress.EndAngle = uc.MappingEchelledouble(-100, 100, -90, 180, (double)e.NewValue);
            }
    
    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Peter Fleischer (former MVP) 19,231 Reputation points
    2021-10-27T03:46:39.37+00:00

    Hi,
    you can use additional dependency properties like thid:

    public static readonly DependencyProperty ArcAngleProperty = DependencyProperty.Register(nameof(ArcAngle), typeof(double), typeof(uc_CircularGaugeType1));
    
    public double ArcAngle
    {
      get { return (double)this.GetValue(ArcAngleProperty); }
      set { this.SetCurrentValue(ArcAngleProperty, MappingScaleDouble(MiniBase, MaxiBase, MiniFinal, MaxiFinal, value)); }
    }
    
    public static double MappingScaleDouble(double miniBase, double MaxiBase, double miniFinal, double maxiFinal, double value)
    {
      return miniFinal + (value - miniBase) * (maxiFinal - miniFinal) / (MaxiBase - miniBase);
    }
    
    public double MiniBase
    {
      get { return (double)GetValue(MiniBaseProperty); }
      set { SetValue(MiniBaseProperty, value); }
    }
    public static readonly DependencyProperty MiniBaseProperty = DependencyProperty.Register(nameof(MiniBase), typeof(double), typeof(uc_CircularGaugeType1));
    
    public double MaxiBase
    {
      get { return (double)GetValue(MaxiBaseProperty); }
      set { SetValue(MaxiBaseProperty, value); }
    }
    public static readonly DependencyProperty MaxiBaseProperty = DependencyProperty.Register(nameof(MaxiBase), typeof(double), typeof(uc_CircularGaugeType1));
    
    public double MiniFinal
    {
      get { return (double)GetValue(MiniFinalProperty); }
      set { SetValue(MiniFinalProperty, value); }
    }
    public static readonly DependencyProperty MiniFinalProperty = DependencyProperty.Register(nameof(MiniFinal), typeof(double), typeof(uc_CircularGaugeType1));
    
    public double MaxiFinal
    {
      get { return (double)GetValue(MaxiFinalProperty); }
      set { SetValue(MaxiFinalProperty, value); }
    }
    public static readonly DependencyProperty MaxiFinalProperty = DependencyProperty.Register(nameof(MaxiFinal), typeof(double), typeof(uc_CircularGaugeType1));
    

  2. Peter Fleischer (former MVP) 19,231 Reputation points
    2021-10-28T09:04:09.403+00:00

    Hi,
    for bindet property you must detect changing of value like this:

    public Point Startpoint { get; set; } // for binding in UI of UserControl  
    public Point Endpoint { get; set; } // for binding in UI of UserControl  
    
    public static readonly DependencyProperty ArcAngleProperty = DependencyProperty.RegisterAttached(nameof(ArcAngle), typeof(double), typeof(uc_CircularGaugeType1), new PropertyMetadata(0.0, OnArcAngleChanged));  
    public static double GetArcAngle(DependencyObject obj) => (double)obj.GetValue(ArcAngleProperty);  
    public static void SetArcAngle(DependencyObject obj, double arc) => obj.SetValue(ArcAngleProperty, arc);  
    private static void OnArcAngleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)  
    {  
      var depObj = d as uc_CircularGaugeType1;  
      if (depObj == null) throw new InvalidOperationException("Error using ArcAngle property.");  
      depObj.ArcAngle = (double)e.NewValue;  
    }  
    public double ArcAngle  
    {  
      get { return (double)this.GetValue(ArcAngleProperty); }  
      set { this.SetCurrentValue(ArcAngleProperty, value); SetStartEndPoint(); }  
    }  
    
    public double MappingScaleDouble(double miniBase, double MaxiBase, double miniFinal, double maxiFinal, double value)  
    {  
      return miniFinal + (value - miniBase) * (maxiFinal - miniFinal) / (MaxiBase - miniBase);  
    }  
    private void SetStartEndPoint()  
    {  
      double arcEnd = Math.PI * MappingScaleDouble(MiniBase, MaxiBase, MiniFinal, MaxiFinal, ArcAngle) / 180;  
      Endpoint = new Point(100 - 90 * Math.Cos(arcEnd), 100 - 90 * Math.Sin(arcEnd));  
      OnPropertyChanged(nameof(Endpoint));  
      double arcStart = Math.PI * MiniFinal / 180;  
      Startpoint = new Point(100 - 90 * Math.Cos(arcStart), 100 - 90 * Math.Sin(arcStart));  
      OnPropertyChanged(nameof(Startpoint));  
    }  
    

    Binding in XAML:

      <Grid>  
        <Grid.RowDefinitions>  
          <RowDefinition/>  
          <RowDefinition Height="auto"/>  
        </Grid.RowDefinitions>  
        <uc:uc_CircularGaugeType1 ArcAngle="{Binding ElementName=sl_value, Path=Value, Mode=TwoWay}"  
                                  MiniBase="{Binding ElementName=sl_miniBase, Path=Value}"  
                                  MaxiBase="{Binding ElementName=sl_maxiBase, Path=Value}"  
                                  MiniFinal="{Binding ElementName=sl_miniFinal, Path=Value}"  
                                  MaxiFinal="{Binding ElementName=sl_maxiFinal, Path=Value}"/>  
        <StackPanel Grid.Row="1">  
          <Label Content="MiniFinal"/>  
          <Slider Name="sl_miniFinal" Minimum="0" Maximum="90" Value="0"/>  
          <Label Content="MaxiFinal"/>  
          <Slider Name="sl_maxiFinal" Minimum="0" Maximum="180" Value="90"/>  
          <Label Content="Value"/>  
          <Slider Name="sl_value" Minimum="0" Maximum="100" Value="100"/>  
        </StackPanel>  
      </Grid>  
    

    Result:

    144436-x.gif

    0 comments No comments