Программа не находит ключ Словаре

58
18 марта 2022, 11:00

Я программирую в Visual Studio 2019

Нашел в сети пример, в котором при растягивании формы меняются размеры элементов. Скачать

При запуске примера, все отлично работает.

Но когда я пытаюсь повторить тоже самое собственноручно, то выскакивает ошибка

System.Collections.Generic.KeyNotFoundException: "Данный ключ отсутствует в словаре."

Ошибка в этом куске кода

 private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        Control CurrentC = (Control)sender;
        if (e.Button == MouseButtons.Left)
        {
            if (dX == 0 || dY == 0)
            {
                dX = e.X;
                dY = e.Y;
            }
            CurrentC.Left += e.X - dX;
            CurrentC.Top += e.Y - dY;
            ThisIsOwerOther(CurrentC);
            return;
        }
        AllFormControls[CurrentC].RefreshLocation(this, CurrentC); //  Вот тут AllFormControls
        dX = 0;
        dY = 0;
    }

При этом я тщательно повторял все тоже самое что и в примере (и дополнительный класс и панель)

В чем может быть проблема

Вот код, для наглядности

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
namespace Students_Book_3._0
{
public partial class Form1 : Form
{
    int dX, dY;
    private Dictionary<Control, GuiViewOfControl> AllFormControls;
    public Form1()
    {
        InitializeComponent();
        AllFormControls = new Dictionary<Control, GuiViewOfControl>();
        foreach (Control CurrC in this.Controls)
        {
            if (CurrC.Name != "Field")
            {
                GuiViewOfControl GuiV = new GuiViewOfControl(this, CurrC);
                AllFormControls.Add(CurrC, GuiV);
                CurrC.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove);
            }
        }
    }
    bool Dragging;
    int mouseX, mouseY;
    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        Control CurrentC = (Control)sender;
        if (e.Button == MouseButtons.Left)
        {
            if (dX == 0 || dY == 0)
            {
                dX = e.X;
                dY = e.Y;
            }
            CurrentC.Left += e.X - dX;
            CurrentC.Top += e.Y - dY;
            ThisIsOwerOther(CurrentC);
            return;
        }
        AllFormControls[CurrentC].RefreshLocation(this, CurrentC);
        dX = 0;
        dY = 0;
    }
    private void ThisIsOwerOther(Control sender)
    {
        foreach (Control cn in this.Controls)
        {
            if (sender == cn)
            {
                continue;
            }
            Rectangle thisContr = new Rectangle(sender.Left, sender.Top, sender.Width, sender.Height);
            Rectangle otherContr = new Rectangle(cn.Left, cn.Top, cn.Width, cn.Height);
            if (thisContr.IntersectsWith(otherContr))
            {
                cn.Refresh();
                sender.Refresh();
            }
        }
    }
    private void Form1_Load(object sender, EventArgs e)
    {
    }
    private void Form1_ResizeEnd(object sender, EventArgs e)
    {
        foreach (Control CurrC in this.Controls)
        {
            double T = AllFormControls[CurrC].Top * this.Height;
            double L = AllFormControls[CurrC].Left * this.Width;
            double H = AllFormControls[CurrC].Height * this.Height;
            double W = AllFormControls[CurrC].Width * this.Width;
            float FontHeight = (float)(AllFormControls[CurrC].Font * H);
            CurrC.Top = (int)T;//AllFormControls[count].Top * this.Height;
            CurrC.Left = (int)L;//AllFormControls[count].Left * this.Width;
            CurrC.Height = (int)H;//AllFormControls[count].Height * this.Height;
            CurrC.Width = (int)W;//AllFormControls[count].Width * this.Width;
            CurrC.Font = new Font(CurrC.Font.FontFamily.Name, FontHeight);
        }
    }
    private void tPanel1_MouseUp(object sender, MouseEventArgs e)
    {
        if (Dragging)
        {
            Dragging = false;
            Cursor.Clip = System.Drawing.Rectangle.Empty;
            // tPanel1.Invalidate();
            this.Cursor = Cursors.Default;
        }
    }
}

}

Зачем мне это нужно - необходимо уместить все что на скрине для любого размера монитора. Встроенные функции мне не помогают

Answer 1

У Form1 не нужно обрабатывать событие MouseMove. Уберите его обработчик в дизайнере форм (окно Properties -> кнопка Events -> правый клик на событии MouseMove -> Reset). И ваш код заработает.

Причина ошибки: когда сама форма вызывала событие MouseMove, она передавалась в метод Form1_MouseMove в качестве sender'а, то есть значением CurrentC была сама форма, но ее как ключа в словаре AllFormControls не было, там ключи - только элементы управления формы.

Answer 2

Вы подписались на событие формы. В переменную кладёте ссылку на форму. Это противоречит всему последующему коду, который, судя по всему, ожидает ссылку на элемент управления.

В Windows Forms для растягивания\сжатия элементов (при различных размерах окна и мониторов) существуют специальные средства, такие, например, как свойства Dock, Aligenment, Anchor . У вас должен быть серьёзный повод для того, чтобы отказаться от них и использовать свой велосипед.

READ ALSO
Передать данные из формы в dataGrid

Передать данные из формы в dataGrid

Имеется класс с переменными, значения переменных записываются во второй форме через например TextBox'ыПроблема в том, чтобы передать эти значения...

188
C# winforms telerik radGridView добавление картинки

C# winforms telerik radGridView добавление картинки

Как добавить картинку в ячейку radGridView?

148
Проблема авторизации в Instagram с помощью InstaSharper

Проблема авторизации в Instagram с помощью InstaSharper

Пишу консольное приложение "Бот instagram" по видеоуроку https://wwwyoutube

62