WPF:如何为垂直滑块设置数字的动态范围?

WPF:如何为垂直滑块设置数字的动态范围?,wpf,slider,Wpf,Slider,我目前正在处理一个WPF MVVM项目,该项目有一个由多个视图使用的用户控件,但具有不同的值范围。 这是我需要的一个例子 如您所见,控件必须根据我需要在滑块中显示的值以不同的行为响应(无论数字如何,这只是一个示例)。 其中一个问题是,项目是使用MVVM设计模式开发的,因此“代码隐藏”不应该是一个好的选择(但如果它解决了问题,对我来说也不错),因此我认为在XAML中执行它可能有点困难 我之前展示的图片是通过在滑块旁边用几个文本块创建一个网格以静态方式完成的,但是不可能保存这个解决方案,因为我需要

我目前正在处理一个WPF MVVM项目,该项目有一个由多个视图使用的用户控件,但具有不同的值范围。 这是我需要的一个例子

如您所见,控件必须根据我需要在滑块中显示的值以不同的行为响应(无论数字如何,这只是一个示例)。 其中一个问题是,项目是使用MVVM设计模式开发的,因此“代码隐藏”不应该是一个好的选择(但如果它解决了问题,对我来说也不错),因此我认为在XAML中执行它可能有点困难

我之前展示的图片是通过在滑块旁边用几个文本块创建一个网格以静态方式完成的,但是不可能保存这个解决方案,因为我需要随时创建一个新的解决方案。 我想开始一个解决方案,使用一个具有设定高度的StackPanel或DockPanel。。。但是,如果您想显示两个值,这不是一个好选项,因为您需要为每个值指定垂直对齐,这听起来不太好

我认为唯一的方法是做一个覆盖或其他什么,允许滑块根据滑块的高度显示刻度。。。有没有办法做到这一点


我只写了几行代码,但没有相关内容,因为我不知道如何解决这个任务。我不需要代码,我需要想法。

我们一起工作,所以我会留下我们找到的解决方案,以防其他人感兴趣

首先,我们创建了两个类

1)从SLIDER继承的类,中间范围(图像中的绿色数字)有两个依赖属性:

class NumberedSlider : System.Windows.Controls.Slider
    {
        public static readonly DependencyProperty RangeMinProperty = DependencyProperty.Register(
                 "RangeMinSlider", typeof(int), typeof(NumberedTickBar), new FrameworkPropertyMetadata(0));

        public int RangeMin
        {
            get { return (int)base.GetValue(RangeMinProperty); }
            set { base.SetValue(RangeMinProperty, value); }
        }

        public static readonly DependencyProperty RangeMaxProperty = DependencyProperty.Register(
                  "RangeMaxSlider", typeof(int), typeof(NumberedTickBar), new FrameworkPropertyMetadata(0));

        public int RangeMax
        {
            get { return (int)base.GetValue(RangeMaxProperty); }
            set { base.SetValue(RangeMaxProperty, value); }
        }
    }
public class NumberedTickBar : TickBar
    {
        public static readonly DependencyProperty RangeMinProperty = DependencyProperty.Register(
            "RangeMin", typeof (int), typeof (NumberedTickBar), new FrameworkPropertyMetadata(0));

        public int RangeMin
        {
            get { return (int) base.GetValue(RangeMinProperty); }
            set { base.SetValue(RangeMinProperty, value); }
        }

        public static readonly DependencyProperty RangeMaxProperty = DependencyProperty.Register(
            "RangeMax", typeof (int), typeof (NumberedTickBar), new FrameworkPropertyMetadata(0));

        public int RangeMax
        {
            get { return (int) base.GetValue(RangeMaxProperty); }
            set { base.SetValue(RangeMaxProperty, value); }
        }

        protected override void OnRender(DrawingContext dc)
        {
            Size size = new Size(base.ActualWidth, base.ActualHeight);

            int tickCount;

            if ((this.Maximum - this.Minimum)%this.TickFrequency == 0)
                tickCount = (int) ((this.Maximum - this.Minimum)/this.TickFrequency);
            else
                tickCount = (int) ((this.Maximum - this.Minimum)/this.TickFrequency) + 1;

            double tickFrequencySize = (size.Height*this.TickFrequency/(this.Maximum - this.Minimum));

            // Draw each tick text
            for (int i = 0; i <= tickCount; i++)
            {
                int value = Convert.ToInt32(this.Minimum + this.TickFrequency*i);

                string text = Convert.ToString(value, 10);
                FormattedText formattedText;
                if (value >= this.RangeMin && value <= this.RangeMax)
                    formattedText = new FormattedText(text, CultureInfo.GetCultureInfo("en-us"),
                                                      FlowDirection.LeftToRight, new Typeface("Arial Rounded MT Bold"), 16,
                                                      Brushes.Green);
                else
                    formattedText = new FormattedText(text, CultureInfo.GetCultureInfo("en-us"),
                                                      FlowDirection.LeftToRight, new Typeface("Arial Rounded MT Bold"), 16,
                                                      Brushes.DarkBlue);

                dc.DrawText(formattedText, new Point(30, (tickFrequencySize*(tickCount - i)-6)));
            }
        }
    }
2)滑块的勾选条类,该类将呈现de编号:

class NumberedSlider : System.Windows.Controls.Slider
    {
        public static readonly DependencyProperty RangeMinProperty = DependencyProperty.Register(
                 "RangeMinSlider", typeof(int), typeof(NumberedTickBar), new FrameworkPropertyMetadata(0));

        public int RangeMin
        {
            get { return (int)base.GetValue(RangeMinProperty); }
            set { base.SetValue(RangeMinProperty, value); }
        }

        public static readonly DependencyProperty RangeMaxProperty = DependencyProperty.Register(
                  "RangeMaxSlider", typeof(int), typeof(NumberedTickBar), new FrameworkPropertyMetadata(0));

        public int RangeMax
        {
            get { return (int)base.GetValue(RangeMaxProperty); }
            set { base.SetValue(RangeMaxProperty, value); }
        }
    }
public class NumberedTickBar : TickBar
    {
        public static readonly DependencyProperty RangeMinProperty = DependencyProperty.Register(
            "RangeMin", typeof (int), typeof (NumberedTickBar), new FrameworkPropertyMetadata(0));

        public int RangeMin
        {
            get { return (int) base.GetValue(RangeMinProperty); }
            set { base.SetValue(RangeMinProperty, value); }
        }

        public static readonly DependencyProperty RangeMaxProperty = DependencyProperty.Register(
            "RangeMax", typeof (int), typeof (NumberedTickBar), new FrameworkPropertyMetadata(0));

        public int RangeMax
        {
            get { return (int) base.GetValue(RangeMaxProperty); }
            set { base.SetValue(RangeMaxProperty, value); }
        }

        protected override void OnRender(DrawingContext dc)
        {
            Size size = new Size(base.ActualWidth, base.ActualHeight);

            int tickCount;

            if ((this.Maximum - this.Minimum)%this.TickFrequency == 0)
                tickCount = (int) ((this.Maximum - this.Minimum)/this.TickFrequency);
            else
                tickCount = (int) ((this.Maximum - this.Minimum)/this.TickFrequency) + 1;

            double tickFrequencySize = (size.Height*this.TickFrequency/(this.Maximum - this.Minimum));

            // Draw each tick text
            for (int i = 0; i <= tickCount; i++)
            {
                int value = Convert.ToInt32(this.Minimum + this.TickFrequency*i);

                string text = Convert.ToString(value, 10);
                FormattedText formattedText;
                if (value >= this.RangeMin && value <= this.RangeMax)
                    formattedText = new FormattedText(text, CultureInfo.GetCultureInfo("en-us"),
                                                      FlowDirection.LeftToRight, new Typeface("Arial Rounded MT Bold"), 16,
                                                      Brushes.Green);
                else
                    formattedText = new FormattedText(text, CultureInfo.GetCultureInfo("en-us"),
                                                      FlowDirection.LeftToRight, new Typeface("Arial Rounded MT Bold"), 16,
                                                      Brushes.DarkBlue);

                dc.DrawText(formattedText, new Point(30, (tickFrequencySize*(tickCount - i)-6)));
            }
        }
    }
公共类编号TickBar:TickBar
{
公共静态只读DependencyProperty RangeMinProperty=DependencyProperty.Register(
“RangeMin”、typeof(int)、typeof(NumberedTickBar)、新框架属性ymatadata(0));
公共int RangeMin
{
获取{return(int)base.GetValue(RangeMinProperty);}
set{base.SetValue(RangeMinProperty,value);}
}
公共静态只读DependencyProperty RangeMaxProperty=DependencyProperty.Register(
“RangeMax”、typeof(int)、typeof(NumberedTickBar)、新的FrameworkPropertyMetadata(0));
公共整数范围最大
{
获取{return(int)base.GetValue(RangeMaxProperty);}
set{base.SetValue(RangeMaxProperty,value);}
}
受保护的覆盖无效OnRender(DrawingContext dc)
{
尺寸=新尺寸(base.ActualWidth,base.ActualHeight);
整数计数;
如果((this.Maximum-this.Minimum)%this.TickFrequency==0)
tickCount=(int)((this.Maximum-this.Minimum)/this.TickFrequency);
其他的
tickCount=(int)((this.Maximum-this.Minimum)/this.TickFrequency)+1;
double tickFrequencySize=(size.Height*this.TickFrequency/(this.Maximum-this.Minimum));
//绘制每个勾号文本

对于(int i=0;i=this.RangeMin&&value我们一起工作,因此我将保留我们找到的解决方案,以防其他人感兴趣

首先,我们创建了两个类

1)从SLIDER继承的类,中间范围(图像中的绿色数字)有两个依赖属性:

class NumberedSlider : System.Windows.Controls.Slider
    {
        public static readonly DependencyProperty RangeMinProperty = DependencyProperty.Register(
                 "RangeMinSlider", typeof(int), typeof(NumberedTickBar), new FrameworkPropertyMetadata(0));

        public int RangeMin
        {
            get { return (int)base.GetValue(RangeMinProperty); }
            set { base.SetValue(RangeMinProperty, value); }
        }

        public static readonly DependencyProperty RangeMaxProperty = DependencyProperty.Register(
                  "RangeMaxSlider", typeof(int), typeof(NumberedTickBar), new FrameworkPropertyMetadata(0));

        public int RangeMax
        {
            get { return (int)base.GetValue(RangeMaxProperty); }
            set { base.SetValue(RangeMaxProperty, value); }
        }
    }
public class NumberedTickBar : TickBar
    {
        public static readonly DependencyProperty RangeMinProperty = DependencyProperty.Register(
            "RangeMin", typeof (int), typeof (NumberedTickBar), new FrameworkPropertyMetadata(0));

        public int RangeMin
        {
            get { return (int) base.GetValue(RangeMinProperty); }
            set { base.SetValue(RangeMinProperty, value); }
        }

        public static readonly DependencyProperty RangeMaxProperty = DependencyProperty.Register(
            "RangeMax", typeof (int), typeof (NumberedTickBar), new FrameworkPropertyMetadata(0));

        public int RangeMax
        {
            get { return (int) base.GetValue(RangeMaxProperty); }
            set { base.SetValue(RangeMaxProperty, value); }
        }

        protected override void OnRender(DrawingContext dc)
        {
            Size size = new Size(base.ActualWidth, base.ActualHeight);

            int tickCount;

            if ((this.Maximum - this.Minimum)%this.TickFrequency == 0)
                tickCount = (int) ((this.Maximum - this.Minimum)/this.TickFrequency);
            else
                tickCount = (int) ((this.Maximum - this.Minimum)/this.TickFrequency) + 1;

            double tickFrequencySize = (size.Height*this.TickFrequency/(this.Maximum - this.Minimum));

            // Draw each tick text
            for (int i = 0; i <= tickCount; i++)
            {
                int value = Convert.ToInt32(this.Minimum + this.TickFrequency*i);

                string text = Convert.ToString(value, 10);
                FormattedText formattedText;
                if (value >= this.RangeMin && value <= this.RangeMax)
                    formattedText = new FormattedText(text, CultureInfo.GetCultureInfo("en-us"),
                                                      FlowDirection.LeftToRight, new Typeface("Arial Rounded MT Bold"), 16,
                                                      Brushes.Green);
                else
                    formattedText = new FormattedText(text, CultureInfo.GetCultureInfo("en-us"),
                                                      FlowDirection.LeftToRight, new Typeface("Arial Rounded MT Bold"), 16,
                                                      Brushes.DarkBlue);

                dc.DrawText(formattedText, new Point(30, (tickFrequencySize*(tickCount - i)-6)));
            }
        }
    }
2)滑块的勾选条类,该类将呈现de编号:

class NumberedSlider : System.Windows.Controls.Slider
    {
        public static readonly DependencyProperty RangeMinProperty = DependencyProperty.Register(
                 "RangeMinSlider", typeof(int), typeof(NumberedTickBar), new FrameworkPropertyMetadata(0));

        public int RangeMin
        {
            get { return (int)base.GetValue(RangeMinProperty); }
            set { base.SetValue(RangeMinProperty, value); }
        }

        public static readonly DependencyProperty RangeMaxProperty = DependencyProperty.Register(
                  "RangeMaxSlider", typeof(int), typeof(NumberedTickBar), new FrameworkPropertyMetadata(0));

        public int RangeMax
        {
            get { return (int)base.GetValue(RangeMaxProperty); }
            set { base.SetValue(RangeMaxProperty, value); }
        }
    }
public class NumberedTickBar : TickBar
    {
        public static readonly DependencyProperty RangeMinProperty = DependencyProperty.Register(
            "RangeMin", typeof (int), typeof (NumberedTickBar), new FrameworkPropertyMetadata(0));

        public int RangeMin
        {
            get { return (int) base.GetValue(RangeMinProperty); }
            set { base.SetValue(RangeMinProperty, value); }
        }

        public static readonly DependencyProperty RangeMaxProperty = DependencyProperty.Register(
            "RangeMax", typeof (int), typeof (NumberedTickBar), new FrameworkPropertyMetadata(0));

        public int RangeMax
        {
            get { return (int) base.GetValue(RangeMaxProperty); }
            set { base.SetValue(RangeMaxProperty, value); }
        }

        protected override void OnRender(DrawingContext dc)
        {
            Size size = new Size(base.ActualWidth, base.ActualHeight);

            int tickCount;

            if ((this.Maximum - this.Minimum)%this.TickFrequency == 0)
                tickCount = (int) ((this.Maximum - this.Minimum)/this.TickFrequency);
            else
                tickCount = (int) ((this.Maximum - this.Minimum)/this.TickFrequency) + 1;

            double tickFrequencySize = (size.Height*this.TickFrequency/(this.Maximum - this.Minimum));

            // Draw each tick text
            for (int i = 0; i <= tickCount; i++)
            {
                int value = Convert.ToInt32(this.Minimum + this.TickFrequency*i);

                string text = Convert.ToString(value, 10);
                FormattedText formattedText;
                if (value >= this.RangeMin && value <= this.RangeMax)
                    formattedText = new FormattedText(text, CultureInfo.GetCultureInfo("en-us"),
                                                      FlowDirection.LeftToRight, new Typeface("Arial Rounded MT Bold"), 16,
                                                      Brushes.Green);
                else
                    formattedText = new FormattedText(text, CultureInfo.GetCultureInfo("en-us"),
                                                      FlowDirection.LeftToRight, new Typeface("Arial Rounded MT Bold"), 16,
                                                      Brushes.DarkBlue);

                dc.DrawText(formattedText, new Point(30, (tickFrequencySize*(tickCount - i)-6)));
            }
        }
    }
公共类编号TickBar:TickBar
{
公共静态只读DependencyProperty RangeMinProperty=DependencyProperty.Register(
“RangeMin”、typeof(int)、typeof(NumberedTickBar)、新框架属性ymatadata(0));
公共int RangeMin
{
获取{return(int)base.GetValue(RangeMinProperty);}
set{base.SetValue(RangeMinProperty,value);}
}
公共静态只读DependencyProperty RangeMaxProperty=DependencyProperty.Register(
“RangeMax”、typeof(int)、typeof(NumberedTickBar)、新的FrameworkPropertyMetadata(0));
公共整数范围最大
{
获取{return(int)base.GetValue(RangeMaxProperty);}
set{base.SetValue(RangeMaxProperty,value);}
}
受保护的覆盖无效OnRender(DrawingContext dc)
{
尺寸=新尺寸(base.ActualWidth,base.ActualHeight);
整数计数;
如果((this.Maximum-this.Minimum)%this.TickFrequency==0)
tickCount=(int)((this.Maximum-this.Minimum)/this.TickFrequency);
其他的
tickCount=(int)((this.Maximum-this.Minimum)/this.TickFrequency)+1;
double tickFrequencySize=(size.Height*this.TickFrequency/(this.Maximum-this.Minimum));
//绘制每个勾号文本

对于(int i=0;i=this.RangeMin&&value这将是一个自定义控件,实际上与MVVM无关。如果您希望它在遵循MVVM模式的应用程序中完美地工作,那么您应该在您的用户控件上公开可绑定到模型的依赖属性。您的所有代码都应该存在于我们的代码隐藏中er控件。不要尝试创建虚拟机用来控制用户控件的伪模型。这将是一个自定义控件,实际上与MVVM无关。如果您希望它在遵循MVVM模式的应用程序中完美工作,那么您应该公开用户控件上可绑定到MVVM的依赖项属性所有代码都应该存在于用户控件的代码隐藏中。不要试图创建虚拟机用来控制用户控件的伪模型。