question

LudoTxx-9485 avatar image
0 Votes"
LudoTxx-9485 asked LudoTxx-9485 answered

WPF - User control - Change value in setter

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));
             }
         }











dotnet-csharpwindows-wpf
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

LudoTxx-9485 avatar image
0 Votes"
LudoTxx-9485 answered

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);
         }
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

PeterFleischer-3316 avatar image
0 Votes"
PeterFleischer-3316 answered LudoTxx-9485 edited

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));



· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thanks for your answer, but this is what i expect when I read your code, the result is excatly the same with properties and hard code :

This and properties :

 <uc:uc_CircularGaugeType1 Name="uc" Height="800" Width="800" MiniBase="0" MaxiBase="100" MiniFinal="0" MaxiFinal="90" ArcAngle="{Binding MyValue}" />


Exact same result than :

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

In fact its look like my "MappingScaleDouble" function is never called in my ArcAngle 'set'.


(FOR previous deleted comments)
My binding works, my arc move perfectly according with my movements, but the value is still 0-100 and not 0-90.

0 Votes 0 ·
PeterFleischer-3316 avatar image
0 Votes"
PeterFleischer-3316 answered

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



x.gif (316.9 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.