У меня есть очень старое программное обеспечение, исходный код которого недоступен, и я даже не уверен, какой язык использовался для его разработки. Я пытаюсь воспроизвести это с помощью форм Windows (С#).
Я наткнулся на особенность, которую понятия не имею, как воспроизвести. На показанном ниже эскизе есть небольшие квадраты, которые можно выбирать с помощью мыши и перемещать с помощью клавиш со стрелками. Расположение этих квадратов также связано с текстовыми полями. Если их расположение изменится, значения в текстовых полях также изменятся и наоборот. На изображениях ниже я указал на один из квадратов красной стрелкой и выделил соответствующее текстовое поле красной рамкой.
До движения:
После движения:
Я не уверен, как можно воспроизвести эту функцию. Я склонен полагать, что эти квадраты должны быть отдельными объектами поверх эскиза, а не частью эскиза. Другими словами, потребуется создать собственный элемент управления Winform, который можно будет выбирать с помощью мыши и перемещать с помощью клавиш со стрелками. Думаю ли я в правильном направлении или есть ли лучший способ решить эту проблему? Если это правильный подход, то как мне создать собственный элемент управления с такими свойствами?
Предполагая, что эти квадратики — цветные кнопки, я реализовал упомянутую вами функцию. С небольшими изменениями вы можете добиться того же.
Три красные кнопки можно выбрать, при нажатии они становятся зелеными, а при выборе их можно перемещать с помощью клавиши со стрелкой. Реализации выходящей логики не существует, но ее легко можно реализовать. Код написан так, чтобы его было легко понять, поэтому оптимизация размера не производилась. Вот реализация кода для Form1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
private List<Button> buttonList = new List<Button>();
private List<TextBox> textboxList = new List<TextBox>();
public Form1()
{
InitializeComponent();
this.KeyPreview = true;
buttonList.Add(button1);
buttonList.Add(button2);
buttonList.Add(button3);
textBox1.Text = button1.Location.ToString();
textBox2.Text = button2.Location.ToString();
textBox3.Text = button3.Location.ToString();
textboxList.Add(textBox1);
textboxList.Add(textBox2);
textboxList.Add(textBox3);
buttonList.ForEach(button =>
{
button.PreviewKeyDown += new PreviewKeyDownEventHandler(button_PreviewKeyDown);
button.LocationChanged += new EventHandler(OnButtonLocationChange);
});
this.KeyDown += new KeyEventHandler(Form1_KeyPress);
}
private void button1_Click(object sender, EventArgs e)
{
button_logic(sender, e);
}
private void OnButtonLocationChange(object sender, EventArgs e)
{
textboxList[buttonList.IndexOf((Button)sender)].Text = ((Button)sender).Location.ToString();
}
private void Form1_KeyPress(object sender, KeyEventArgs e)
{
if (buttonList.FirstOrDefault(x => x.BackColor == Color.Green) == null)
return;
if (e.KeyCode == Keys.Up)
{
Button tempButton = buttonList.First(x => x.BackColor == Color.Green);
buttonList.First(x => x.BackColor == Color.Green).Location = new Point(tempButton.Location.X, tempButton.Location.Y - 10);
}
else if (e.KeyCode == Keys.Down)
{
Button tempButton = buttonList.First(x => x.BackColor == Color.Green);
buttonList.First(x => x.BackColor == Color.Green).Location = new Point(tempButton.Location.X, tempButton.Location.Y + 10);
}
else if (e.KeyCode == Keys.Left)
{
Button tempButton = buttonList.First(x => x.BackColor == Color.Green);
buttonList.First(x => x.BackColor == Color.Green).Location = new Point(tempButton.Location.X - 10, tempButton.Location.Y );
}
else if (e.KeyCode == Keys.Right)
{
Button tempButton = buttonList.First(x => x.BackColor == Color.Green);
buttonList.First(x => x.BackColor == Color.Green).Location = new Point(tempButton.Location.X + 10, tempButton.Location.Y);
}
}
private void button_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
var keys = new[] { Keys.Left, Keys.Right, Keys.Up, Keys.Down };
if (keys.Contains(e.KeyData))
e.IsInputKey = true;
}
private void button2_Click(object sender, EventArgs e)
{
button_logic(sender, e);
this.Focus();
}
private void button3_Click(object sender, EventArgs e)
{
button_logic(sender, e);
}
private void button_logic(object sender, EventArgs e)
{
foreach(Button button in buttonList)
{
if ((Button)sender == button)
{
button.BackColor = Color.Green;
}
else
{
button.BackColor = Color.Red;
}
}
this.Focus();
}
}
}
Спасибо, Натан. В итоге я создал собственный элемент управления панелью, который можно выбирать и перемещать с помощью клавиш со стрелками, но ваш ответ тоже очень интересен. По-прежнему отсутствует реверс, при котором расположение кнопки меняется при изменении содержимого текстового поля, но это не должно быть сложно реализовать. С помощью специальной раскраски кнопок я смогу получить от вашего ответа то, что хочу. Еще раз спасибо.
Для меня они выглядят как простые флажки, поэтому я ожидаю массив элементов управления, и вы можете «перемещать» элементы управления в Winforms с помощью свойств top/left и некоторой перерисовки. Если этот зеленый квадрат находится в левом верхнем углу пользовательского интерфейса, это облегчит задачу, поскольку положение флажка будет абсолютным, а не требует каких-либо смещений :)