C# trackbar 不支持浮点数

C# trackbar 不支持浮点数

trackbar中的一次更改量可以为小数吗,比方说想设置value的值是从0到3,但是在trackbar中可以定义300或者30个点来表示,把tickfrequency的值可以设置为小数吗,或者在最大最小中如何更改,实现value值为0-12但却可以有120个调节点的效果,主要目的是为了界面的美观,点多了看着像是可以调节的横条,而不是一个一个僵硬的选择点,如果小数调节不可实现,有可以将value为1~12,但hi把12个调节点变为一个整体调节横条而不是之前那种只有12个调节点的方法吗

img

TickFrequency是int类型的,无法设置为小数。Maximum设置120,换算下就行

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632

【以下回答由 GPT 生成】

回答:

C# 的 trackbar 控件是不支持直接设置小数范围和小数的 tick frequency 的,因为 tick frequency 属性只能接受一个整数值。不过,我们可以通过一些技巧来实现类似的效果。

解决方案一:将小数范围映射到整数范围 我们可以将小数范围映射到整数范围,并通过 trackbar 的 Value 属性来表示该整数范围内的值。然后,再通过一些转换函数将整数值转换为对应的小数值,以及将小数值转换为整数值。

以下是一个示例代码实现:

public partial class Form1 : Form
{
    private double minValue = 0;
    private double maxValue = 3;
    private int numTicks = 300;

    public Form1()
    {
        InitializeComponent();

        trackBar1.Minimum = 0;
        trackBar1.Maximum = numTicks;
        trackBar1.TickFrequency = numTicks / (int)(maxValue - minValue);
    }

    private double MapValue(int intValue)
    {
        double range = maxValue - minValue;
        double stepSize = range / numTicks;
        return minValue + (intValue * stepSize);
    }

    private int MapValue(double floatValue)
    {
        double range = maxValue - minValue;
        double stepSize = range / numTicks;
        return (int)Math.Round((floatValue - minValue) / stepSize);
    }

    private void trackBar1_Scroll(object sender, EventArgs e)
    {
        double value = MapValue(trackBar1.Value);
        // 使用 value 值进行其他操作
    }
}

在这个示例中,我们将 trackbar 的最小值设置为0,最大值设置为numTicks(即调节点个数),tick frequency 设置为 numTicks / (int)(maxValue - minValue)。然后,通过 MapValue 函数将 trackbar 的整数值映射为对应的浮点数值,以及将浮点数值映射为 trackbar 的整数值。

解决方案二:使用自定义的滑块控件 另一种解决方案是使用自定义的滑块控件,以实现更复杂的效果。这需要更多的代码和绘图技巧,但可以实现更高度自定义的界面效果。

以下是一个示例代码实现该自定义滑块控件的思路:

public partial class FloatTrackBar : Control
{
    private float minValue = 0;
    private float maxValue = 12;
    private int numTicks = 120;

    private float value;
    private Rectangle sliderRect;
    private bool isDragging;

    public float Value
    {
        get { return value; }
        set
        {
            this.value = Math.Min(Math.Max(minValue, value), maxValue);
            Invalidate();
        }
    }

    public event EventHandler ValueChanged;

    public FloatTrackBar()
    {
        SetStyle(ControlStyles.OptimizedDoubleBuffer |
                 ControlStyles.AllPaintingInWmPaint |
                 ControlStyles.ResizeRedraw |
                 ControlStyles.UserPaint |
                 ControlStyles.Selectable,
                 true);
        Size = new Size(200, 20);
        value = minValue;
        sliderRect = new Rectangle(0, 0, 10, Height);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.Clear(BackColor);
        float range = maxValue - minValue;
        float stepSize = range / numTicks;

        for (int i = 0; i <= numTicks; i++)
        {
            float tickValue = minValue + (i * stepSize);
            int x = (int)((tickValue / range) * (Width - sliderRect.Width));
            e.Graphics.DrawLine(Pens.Black, x, 0, x, Height);
        }

        sliderRect.X = (int)(((Value - minValue) / range) * (Width - sliderRect.Width));
        e.Graphics.FillRectangle(Brushes.Blue, sliderRect);
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);
        if (sliderRect.Contains(e.Location))
        {
            isDragging = true;
        }
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);
        if (isDragging)
        {
            int x = Math.Min(Math.Max(0, e.X), Width - sliderRect.Width);
            Value = minValue + (maxValue - minValue) * (x / (float)(Width - sliderRect.Width));
            ValueChanged?.Invoke(this, EventArgs.Empty);
        }
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        base.OnMouseUp(e);
        isDragging = false;
    }
}

在这个示例中,我们创建了一个名为 FloatTrackBar 的自定义控件。它继承自 Control 并重写了一些基本方法。在 OnPaint 方法中进行绘制,通过计算滑块的位置来绘制调节点和滑块本身。在 OnMouseDownOnMouseMoveOnMouseUp 方法中实现了滑动滑块的逻辑。

使用该自定义控件时,可以像使用其他控件一样处理其 ValueChanged 事件,以获取滑块值的变化。

请注意,这只是两种可能的解决方案,具体取决于你的应用需求和界面设计。希望这些解决方案能帮助到你!


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^