c# - How to calculator exactly margin value of boder process in range slider? -


i create rangeslider control: xaml:

<style x:key="rangesliderrepeatbutton" targettype="{x:type repeatbutton}">     <setter property="snapstodevicepixels" value="true" />     <setter property="overridesdefaultstyle" value="true" />     <setter property="template">         <setter.value>             <controltemplate targettype="{x:type repeatbutton}">                 <border background="transparent" height="6" />             </controltemplate>         </setter.value>     </setter> </style>  <style x:key="rangesliderthumbstyle" targettype="{x:type thumb}">     <setter property="snapstodevicepixels" value="true" />     <setter property="overridesdefaultstyle" value="true" />     <setter property="verticalalignment" value="center" />     <setter property="template">         <setter.value>             <controltemplate targettype="thumb">                     <grid margin="0,0,0,10">                         <label x:name="part_valueofslider" content="{binding value, relativesource={relativesource ancestortype={x:type slider}}}"                                    margin="0 -20 0 0"                                    horizontalalignment="center"                                    foreground="red"/>                         <path x:name="part_rectangle" fill="gray">                             <path.data>                                 <rectanglegeometry rect="0,0 10 9" radiusx="2" radiusy="2"></rectanglegeometry>                             </path.data>                             <path.effect>                                 <dropshadoweffect shadowdepth="2" blurradius="3" color="black" opacity="0.4" direction="270" />                             </path.effect>                         </path>                         <path x:name="part_traingle" data="m 0 8 l 5 14 l 10 8 z" fill="gray" >                             <path.effect>                                 <dropshadoweffect shadowdepth="1" blurradius="0" color="black" opacity="0.4" direction="270" />                             </path.effect>                         </path>                     </grid>                 <controltemplate.triggers>                     <trigger property="ismouseover" value="true">                         <setter targetname="part_rectangle" property="fill" value="{dynamicresource labledsliderthumbhoverbrush}" />                         <setter targetname="part_traingle" property="fill" value="{dynamicresource labledsliderthumbhoverbrush}" />                     </trigger>                     <trigger property="ismousecaptured" value="true">                         <setter targetname="part_rectangle" property="fill" value="{dynamicresource labledsliderthumbfocusesbrush}" />                         <setter targetname="part_traingle" property="fill" value="{dynamicresource labledsliderthumbfocusesbrush}" />                     </trigger>                 </controltemplate.triggers>             </controltemplate>         </setter.value>     </setter> </style>  <style x:key="rangeslider" targettype="{x:type slider}">     <setter property="focusable" value="false"/>     <setter property="snapstodevicepixels" value="true" />     <setter property="overridesdefaultstyle" value="true" />     <setter property="template">         <setter.value>             <controltemplate targettype="{x:type slider}">                 <grid>                     <grid.rowdefinitions>                         <rowdefinition height="30" />                     </grid.rowdefinitions>                     <grid.columndefinitions>                         <columndefinition width="*" minwidth="{templatebinding minwidth}"/>                         <columndefinition width="auto"/>                         <columndefinition width="auto"/>                     </grid.columndefinitions>                     <track grid.column="0" x:name="part_track">                         <track.decreaserepeatbutton>                             <repeatbutton style="{staticresource rangesliderrepeatbutton}" command="slider.decreaselarge" />                         </track.decreaserepeatbutton>                         <track.thumb>                             <thumb x:name="part_thumb" style="{staticresource rangesliderthumbstyle}"/>                         </track.thumb>                         <track.increaserepeatbutton>                             <repeatbutton style="{staticresource rangesliderrepeatbutton}" command="slider.increaselarge" />                         </track.increaserepeatbutton>                     </track>                 </grid>             </controltemplate>         </setter.value>     </setter> </style>  <grid x:name="layoutroot" background="#ff878889">     <grid.columndefinitions>         <columndefinition width="47*"/>         <columndefinition width="353*"/>     </grid.columndefinitions>     <border verticalalignment="center"                              borderbrush="black"                              background="black"                              height="10"                              grid.column="0"                             borderthickness="1"                             padding="2"                             cornerradius="4" grid.columnspan="2" margin="0,5"/>      <border x:name="progressborder"                              snapstodevicepixels="true"                              background="blue"                               borderbrush="blue"                              height="6"                             verticalalignment="center" grid.columnspan="2" margin="0,7"                             />     <slider x:name="lowerslider"             minimum="{binding relativesource={relativesource ancestortype=local:rangeslider}, path=minimum, mode=twoway}"             maximum="{binding relativesource={relativesource ancestortype=local:rangeslider}, path=maximum, mode=twoway}"             value="{binding relativesource={relativesource ancestortype=local:rangeslider}, path=lowervalue, mode=twoway}"             style="{staticresource sliderstyle}" grid.columnspan="2" />     <slider x:name="upperslider"             minimum="{binding relativesource={relativesource ancestortype=local:rangeslider}, path=minimum, mode=twoway}"             maximum="{binding relativesource={relativesource ancestortype=local:rangeslider}, path=maximum, mode=twoway}"             value="{binding relativesource={relativesource ancestortype=local:rangeslider}, path=uppervalue, mode=twoway}"             style="{staticresource sliderstyle}" grid.column="1" /> </grid> 

rangeslider.cs

public partial class rangeslider : usercontrol {     public rangeslider()     {         this.initializecomponent();         this.layoutupdated += new eventhandler(rangeslider_layoutupdated);     }      void rangeslider_layoutupdated(object sender, eventargs e)     {         setprogressborder();     }      private void setprogressborder()     {         double lowerpoint = (this.actualwidth * (lowervalue - minimum)) / (maximum - minimum);         double upperpoint = (this.actualwidth * (uppervalue - minimum)) / (maximum - minimum);         upperpoint = this.actualwidth - upperpoint;          progressborder.margin = new thickness(lowerpoint, 0, upperpoint, 0);     }      public double minimum     {         { return (double)getvalue(minimumproperty); }         set { setvalue(minimumproperty, value); }     }      public double maximum     {         { return (double)getvalue(maximumproperty); }         set { setvalue(maximumproperty, value); }     }      public double lowervalue     {         { return (double)getvalue(lowervalueproperty); }         set { setvalue(lowervalueproperty, value); }     }      public double uppervalue     {         { return (double)getvalue(uppervalueproperty); }         set { setvalue(uppervalueproperty, value); }     }      public static readonly dependencyproperty minimumproperty =         dependencyproperty.register("minimum", typeof(double), typeof(rangeslider), new uipropertymetadata(0d, new propertychangedcallback(propertychanged)));      public static readonly dependencyproperty lowervalueproperty =         dependencyproperty.register("lowervalue", typeof(double), typeof(rangeslider), new uipropertymetadata(10d, new propertychangedcallback(propertychanged)));      public static readonly dependencyproperty uppervalueproperty =         dependencyproperty.register("uppervalue", typeof(double), typeof(rangeslider), new uipropertymetadata(90d, new propertychangedcallback(propertychanged)));      public static readonly dependencyproperty maximumproperty =         dependencyproperty.register("maximum", typeof(double), typeof(rangeslider), new uipropertymetadata(100d, new propertychangedcallback(propertychanged)));      private static void propertychanged(dependencyobject d, dependencypropertychangedeventargs e)     {         rangeslider slider = (rangeslider)d;         if (e.property == rangeslider.lowervalueproperty)         {             slider.upperslider.value = math.max(slider.upperslider.value, slider.lowerslider.value);         }         else if (e.property == rangeslider.uppervalueproperty)         {             slider.lowerslider.value = math.min(slider.upperslider.value, slider.lowerslider.value);         }         slider.setprogressborder();     } } 

it work fine when label x:name="part_valueofslider"contain small value. work fine

when label x:name="part_valueofslider" has big value, progressborder display show not expected not work fine yet

how set progressborder work fine? me !!!

i using 1 slider work fine me xaml code slider

<controltemplate x:key="timerangeslidertemplate" targettype="{x:type slider}">     <stackpanel>         <border snapstodevicepixels="true" borderbrush="{templatebinding borderbrush}" borderthickness="{templatebinding borderthickness}">             <grid>                 <grid.rowdefinitions>                     <rowdefinition height="auto"/>                     <rowdefinition height="auto" minheight="{templatebinding minheight}"/>                     <rowdefinition height="auto"/>                 </grid.rowdefinitions>                  <rectangle x:name="part_selectionrange"/>                  <track x:name="part_track" grid.row="1">                     <track.thumb>                         <thumb x:name="thumb">                             <thumb.template>                                 <controltemplate targettype="thumb">                                         <rectangle fill="red"                                                 stroke="black"                                                strokethickness="1"                                                 width="10"                                                height="18"                                                snapstodevicepixels="true"/>                                 </controltemplate>                             </thumb.template>                         </thumb>                     </track.thumb>                 </track>             </grid>         </border>     </stackpanel> </controltemplate>  <style targettype="{x:type sliders:timerangeslider}">     <setter property="template">         <setter.value>             <controltemplate targettype="{x:type sliders:timerangeslider}">                 <grid verticalalignment="top">                     <grid.rowdefinitions>                         <rowdefinition height="auto"/>                         <rowdefinition height="auto"/>                     </grid.rowdefinitions>                     <stackpanel orientation="horizontal">                         <textblock text="{binding elementname=part_lowerslider,path=value}"  foreground="red" verticalalignment="top" margin="{binding elementname=part_selectedrect,path=margin}"/>                         <textblock x:name="part_rightthumpvalue" text="{binding elementname=part_upperslider,path=value}"  foreground="red" verticalalignment="top" horizontalalignment="left"/>                     </stackpanel>                     <grid grid.row="1">                         <border borderthickness="0,1,0,0" borderbrush="black" verticalalignment="center" height="1" margin="5,0,5,0"/>                          <rectangle x:name="part_selectedrect"  fill="green" height="10" horizontalalignment="left"/>                         <slider x:name="part_lowerslider"                             minimum="{templatebinding minimum}"                             maximum="{templatebinding maximum}"                             value="{templatebinding lowervalue}"                             template="{staticresource timerangeslidertemplate}"                             margin="0,0,0,0"/>                          <slider x:name="part_upperslider"                             minimum="{templatebinding minimum}"                             maximum="{templatebinding maximum}"                             value="{templatebinding uppervalue}"                             template="{staticresource timerangeslidertemplate}"                             margin="0,0,0,0"/>                     </grid>                 </grid>             </controltemplate>         </setter.value>     </setter> </style> 

and here cs file of xaml

 public class timerangeslider : control {     private const string partname_lowerslider = "part_lowerslider";     private const string partname_upperslider = "part_upperslider";     private const string partname_selectedregion = "part_selectedrect";     private const string part_rightthumpvalue = "part_rightthumpvalue";      private slider lowerslider;     private slider upperslider;     rectangle selectedrect;     textblock righttext;      public timerangeslider()     {         this.defaultstylekey = typeof(timerangeslider);         this.loaded += timerangeslider_loaded;     }      void timerangeslider_loaded(object sender, routedeventargs e)     {         lowerslider.valuechanged += lowerslider_valuechanged;         upperslider.valuechanged += upperslider_valuechanged;          lowerslider.minimum = minimum;         lowerslider.maximum = maximum;         lowerslider.value = lowervalue;          upperslider.minimum = minimum;         upperslider.maximum = maximum;         upperslider.value = uppervalue;          setview();     }      public override void onapplytemplate()     {         lowerslider = this.gettemplatechild(partname_lowerslider) slider;         upperslider = this.gettemplatechild(partname_upperslider) slider;         selectedrect = this.gettemplatechild(partname_selectedregion) rectangle;         righttext = this.gettemplatechild(part_rightthumpvalue) textblock;          base.onapplytemplate();     }       private void lowerslider_valuechanged(object sender, routedpropertychangedeventargs<double> e)     {         upperslider.value = math.max(upperslider.value, lowerslider.value);         setview();     }      private void upperslider_valuechanged(object sender, routedpropertychangedeventargs<double> e)     {         lowerslider.value = math.min(upperslider.value, lowerslider.value);         setview();     }      private void setview()     {         lowervalue = lowerslider.value;         uppervalue = upperslider.value;          var unit = lowerslider.actualwidth / maximum;          var leftmargin = lowervalue * unit;          if (uppervalue > lowervalue)         {             var width = (uppervalue - lowervalue) * unit;             selectedrect.width = width;         }          selectedrect.margin = new thickness(leftmargin, 0, 0, 0);         righttext.margin = new thickness(selectedrect.width-20, 0, 0, 0);      }      public double minimum     {         { return (double)getvalue(minimumproperty); }         set { setvalue(minimumproperty, value); }     }      public static readonly dependencyproperty minimumproperty =         dependencyproperty.register("minimum", typeof(double), typeof(timerangeslider), new uipropertymetadata(0d));      public double lowervalue     {         { return (double)getvalue(lowervalueproperty); }         set { setvalue(lowervalueproperty, value); }     }      public static readonly dependencyproperty lowervalueproperty =         dependencyproperty.register("lowervalue", typeof(double), typeof(timerangeslider), new uipropertymetadata(0d));      public double uppervalue     {         { return (double)getvalue(uppervalueproperty); }         set { setvalue(uppervalueproperty, value); }     }      public static readonly dependencyproperty uppervalueproperty =         dependencyproperty.register("uppervalue", typeof(double), typeof(timerangeslider), new uipropertymetadata(0d));      public double maximum     {         { return (double)getvalue(maximumproperty); }         set { setvalue(maximumproperty, value); }     }      public static readonly dependencyproperty maximumproperty =         dependencyproperty.register("maximum", typeof(double), typeof(timerangeslider), new uipropertymetadata(1d)); } 

and usage of control

 <slidercontrol:timerangeslider x:name="slider"                             margin="10"                             lowervalue="30"                            uppervalue="70"                            minimum="0"                            maximum="100"                            /> 

Comments