Bug 21181 - Slider does not allow us set/bind Minimal value more than 1
Summary: Slider does not allow us set/bind Minimal value more than 1
Status: RESOLVED NOT_ON_ROADMAP
Alias: None
Product: Forms
Classification: Xamarin
Component: Forms ()
Version: 1.1.1
Hardware: PC Mac OS
: Normal minor
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2014-07-08 14:33 UTC by Prashant Cholachagudda
Modified: 2016-03-15 19:21 UTC (History)
9 users (show)

Tags: ac
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED NOT_ON_ROADMAP

Description Prashant Cholachagudda 2014-07-08 14:33:50 UTC
Slider does not allow us to set/bind Minimum property to greater than 1, but it is allowed to set
the value greater than 1 for Maximum property.

Works: 
<Slider x:Name="slider" Minimum="0" Maximum="360" />

This throws an exception:
<Slider x:Name="slider" Minimum="1" Maximum="360" />

System.ArgumentException: Value was an invalid value for Minimum
Parameter name: value
  at Xamarin.Forms.BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Boolean clearBindings, Boolean raiseOnEqual, Boolean checkaccess) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.BindableObject.SetValue (Xamarin.Forms.BindableProperty property, System.Object value, Boolean checkaccess) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.BindableObject.SetValue (Xamarin.Forms.BindableProperty property, System.Object value) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.Xaml.BaseValueNode.SetPropertyValue (System.Object xamlelement, XmlName propertyName, System.Object value) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.Xaml.ValueNode.ApplyTo (System.Object source, XmlName propertyName, INameScope namescope) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.Xaml.INodeExtension.ApplyProperties (IElementNode node, System.Object source, INameScope namescope) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.Xaml.ElementNode.ApplyProperties (INameScope namescope) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.Xaml.ElementNode.Create (IElement parent, INameScope namescope) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.Xaml.ListNode.ApplyTo (System.Object source, XmlName propertyName, INameScope namescope) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.Xaml.INodeExtension.ApplyProperties (IElementNode node, System.Object source, INameScope namescope) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.Xaml.ElementNode.ApplyProperties (INameScope namescope) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.Xaml.ElementNode.Create (IElement parent, INameScope namescope) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.Xaml.ElementNode.ApplyTo (System.Object source, XmlName propertyName, INameScope namescope) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.Xaml.INodeExtension.ApplyProperties (IElementNode node, System.Object source, INameScope namescope) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.Xaml.RootNode.ApplyProperties (INameScope namescope) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.Xaml.XamlLoader.Load (Xamarin.Forms.VisualElement view, System.String xaml) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.Xaml.XamlLoader.Load (Xamarin.Forms.VisualElement view, System.Type callingType) [0x00000] in <filename unknown>:0
  at Xamarin.Forms.Xaml.Extensions.LoadFromXaml[MyPage] (XamlTestPCL.MyPage view, System.Type callingType) [0x00000] in <filename unknown>:0
  at XamlTestPCL.MyPage.InitializeComponent () [0x0000c] in /Users/prashantvc/Desktop items/Xamarin/78116/XamlTestPCL/XamlTestPCL/obj/Debug/MyPage.xaml.g.cs:24
  at XamlTestPCL.MyPage..ctor () [0x00008] in /Users/prashantvc/Desktop items/Xamarin/78116/XamlTestPCL/XamlTestPCL/MyPage.xaml.cs:12
  at XamlTestPCL.App.GetMainPage () [0x00001] in /Users/prashantvc/Desktop items/Xamarin/78116/XamlTestPCL/XamlTestPCL/App.cs:11
  at XamlTestPCL.iOS.AppDelegate.FinishedLaunching (MonoTouch.UIKit.UIApplication app, MonoTouch.Foundation.NSDictionary options) [0x00021] in /Users/prashantvc/Desktop items/Xamarin/78116/XamlTestPCL/iOS/AppDelegate.cs:23
  at at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
  at XamlTestPCL.iOS.Application.Main (System.String[] args) [0x00008] in /Users/prashantvc/Desktop items/Xamarin/78116/XamlTestPCL/iOS/Main.cs:17
Comment 2 Kurt Claeys 2014-07-08 15:05:09 UTC
Got the some issue, setting Minimum to anything else than 0 causes an exception.


Works :
 _theSlider = new Slider
            {
                Minimum = 0,
                Maximum = maxValue,
                Value = 1,
              ...
            };


Fails :
 _theSlider = new Slider
            {
                Minimum = 1,
                Maximum = maxValue,
                Value = 1,
              ...
            };
Comment 3 Isaac Rosenberg 2014-07-22 16:34:54 UTC
Temporary workaround if you're working in code: pass your values in the constructor. 

Documentation: http://iosapi.xamarin.com/?link=C%3aXamarin.Forms.Slider.Slider(System.Double%2cSystem.Double%2cSystem.Double)

This works: 

var slider = new Slider (10, 100, 1);

This doesn't: 

var slider = new Slider {
   Minimum = 10, 
   Maximum = 100, 
   Value = 1
};

Nor does this: 

var slider = new Slider ();
slider.Minimum = 10;
Comment 4 Kraig Brockschmidt 2015-03-06 17:43:51 UTC
As described on http://forums.xamarin.com/discussion/19131/invalid-value-for-slider-minimum, the issue seems to be that setting Minimum before setting Maximum causes a validation error. It would seem that the Slider is defaulting both Minimum and Maximum to zero, and when setting Minimum to a non-zero value during XAML processing, it's doing so without remembering that Maximum is set to its default of zero. So because Max < Min in this case, it throws.

It works if you specify Maximum first in the XAML, before Minimum. I consider this a real bug, because the order shouldn't matter.
Comment 5 Adam Kemp 2015-07-01 11:04:09 UTC
We made the same mistake in our internal control library, and it was also difficult to use as a result. A better API (at least for programmatic use) is to use a single Range property instead of individual min/max properties. If you do provide individual min/max properties then they should never throw, and instead they should just force the range to be sane after applying the new value. So if you try to apply a new minimum M0 that is greater than the current maximum you would end up with a range of zero size (M0, M0). Likewise, applying a maximum M1 that is smaller than the current minimum results in a range of (M1, M1). When applying two new value one after another you will always get the sane result assuming that the two values were sane to begin with (i.e., assuming that M0 <= M1), regardless of the order in which they were set.

Clamping the current value is a problem, however. If you want to ensure that the value is clamped within the new range properly then the only sane thing to do is to set both the minimum and the maximum atomically using a single property. That's why it makes sense to have a Range property that includes both.

On a related note, looking at the code in the assembly browser, I can see that Xamarin themselves can't make up their mind about whether to throw or coerce. Look at this code from the constructor:

		public Slider(double min, double max, double val)
		{
			if (min >= max)
			{
				throw new ArgumentOutOfRangeException("min");
			}
			if (max > this.Minimum)
			{
				this.Maximum = max;
				this.Minimum = min;
			}
			else
			{
				this.Minimum = min;
				this.Maximum = max;
			}
			this.Value = val.Clamp(min, max);
		}

There's no point in doing the swapping because in that case you would have thrown already.