我正在制作类似TrackBar的用户控件。
用户可以单击面板并拖动它以更改int SelectedMin
。
我想绘制SelectedMin
面板以围绕鼠标,因为我拖动而不是从鼠标开始。换句话说,我希望面板的中心显示在我的SelectedMin
值,而不是SelectedMin
面板的左侧。
我认为这应该使用ToolboxCustomTrackBar_Paint()
方法中的一行:
minPanel.Location = new Point((SelectedMin * Width / (Max - Min)) - PanelWidth/2, LabelHeight);
程序正常启动,最初显示的面板只有一半,表示... - PanelWidth/2
正在工作,但是当我点击面板拖动它时,它将面板左侧居中放置鼠标光标是。
顶部图像是目前发生的事情。最底层的图像是我想要实现的目标。
相关代码:
private int min = 0;
private int max = 1000;
private int selectedMin = 200;
private int labelWidth = 0;
private int labelHeight = 200;
private int panelWidth = 10;
public int Min
{
get { return min; }
set { min = value; Invalidate(); }
}
public int Max
{
get { return max; }
set { max = value; Invalidate(); }
}
public int SelectedMin
{
get { return selectedMin; }
set
{
if (value >= Min && value <= Max)
{
selectedMin = value;
Invalidate();
}
}
}
public int LabelWidth
{
get { return labelWidth; }
set { labelWidth = value; Invalidate(); }
}
public int LabelHeight
{
get { return labelHeight; }
set { labelHeight = value; Invalidate(); }
}
public int PanelWidth
{
get { return panelWidth; }
set { panelWidth = value; Invalidate(); }
}
public ToolboxCustomTrackBar()
{
InitializeComponent();
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
selectionWidth = (Max - Min) / Width;
minLabel.Text = "0";
LabelWidth = minLabel.Width;
}
private void ToolboxCustomTrackBar_Paint(object sender, PaintEventArgs e)
{
foreach (var panel in panels)
{
panel.Height = Height - LabelHeight;
if (panel != backdropPanel)
{
panel.Width = PanelWidth;
}
}
minPanel.Location = new Point((SelectedMin * Width / (Max - Min)) - PanelWidth/2, LabelHeight);
}
private void minPanel_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
SelectedMin += Min + e.X * (Max - Min) / Width;
}
}
答案 0 :(得分:0)
刚刚在我自己创建了一个跟踪栏,它似乎有效:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace TestProjectWinforms
{
public partial class TrackBar : UserControl
{
private int _CurrentValue;
private bool _IsDragging;
private int _MaximumValue;
private int _MinimumValue;
public TrackBar()
{
InitializeComponent();
TrackColor = Color.Red;
TrackWidth = 10;
MinimumValue = 0;
MaximumValue = 10000;
CurrentValue = 3000;
HotTrackEnabled = true;
}
public event EventHandler CurrentValueChanged;
public int CurrentValue
{
get => _CurrentValue;
set
{
_CurrentValue = value;
ValidateCurrentValue();
Invalidate();
RaiseEvent(CurrentValueChanged);
}
}
public bool HotTrackEnabled { get; set; }
public int MaximumValue
{
get => _MaximumValue;
set
{
_MaximumValue = value;
if (_MaximumValue < _MinimumValue)
_MaximumValue = _MinimumValue;
ValidateCurrentValue();
Invalidate();
}
}
public int MinimumValue
{
get => _MinimumValue;
set
{
_MinimumValue = value;
if (_MinimumValue > _MaximumValue)
_MinimumValue = _MaximumValue;
ValidateCurrentValue();
Invalidate();
}
}
public Color TrackColor { get; set; }
public int TrackWidth { get; set; }
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (HotTrackEnabled)
_IsDragging = true;
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (_IsDragging)
{
UpdateCurrentValueFromPosition(e.X);
Invalidate();
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
_IsDragging = false;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
using (var brush = new SolidBrush(TrackColor))
{
e.Graphics.FillRectangle(brush, CreateRectangle());
}
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
Invalidate();
}
private RectangleF CreateRectangle()
{
var position = GetRectanglePosition();
var rectangle = new RectangleF(position, 0, TrackWidth, Height);
return rectangle;
}
private float GetRectanglePosition()
{
var range = _MaximumValue - _MinimumValue;
var value = _CurrentValue - _MinimumValue;
var percentage = (float)value * 100 / range;
var position = percentage * Width / 100;
return position - (float)TrackWidth / 2;
}
private void RaiseEvent(EventHandler handler)
{
handler?.Invoke(this, EventArgs.Empty);
}
private void UpdateCurrentValueFromPosition(float x)
{
var percentage = x * 100 / Width;
var range = _MaximumValue - _MinimumValue;
var rawValue = percentage * range / 100;
var value = rawValue + _MinimumValue;
CurrentValue = (int)Math.Round(value);
}
private void ValidateCurrentValue()
{
if (_CurrentValue < _MinimumValue)
_CurrentValue = _MinimumValue;
if (_CurrentValue > _MaximumValue)
_CurrentValue = _MaximumValue;
}
}
}