ThisandThatorWhat Ответов: 2

System.invalidcastexception: 'указанное приведение недопустимо.' с тегами


Я пытаюсь использовать это свойство тега, но оно не работает должным образом, потому что приведение недопустимо

Я поместил все теги в property = Borderstyle.Никто

Что я уже пробовал:

Это работает здесь

private void PictureBoxes_MouseEnter(object sender, EventArgs e)
        {
            PictureBox p = sender as PictureBox;
            if (p != null)
            {
                p.BorderStyle = BorderStyle.Fixed3D;
            }

        }



private void PictureBoxes_MouseClick(object sender, MouseEventArgs e)
        {


            PictureBox pBox = sender as PictureBox;

            

            if (e.Button == MouseButtons.Left)
            {
                pBox.MouseLeave -= PictureBoxes_MouseLeave;
                pBox.ImageLocation = (startupPath + @"img\sd0.png");
            }
            else if (e.Button == MouseButtons.Right)
            {
                pBox.MouseLeave -= PictureBoxes_MouseLeave; // prevent double subscription
                pBox.MouseLeave += PictureBoxes_MouseLeave;
            }

        }



Это не работает

private void PictureBoxes_MouseLeave(object sender, EventArgs e)
        {
            PictureBox p = sender as PictureBox;
            
            if (p != null)
            {
                try
                {
                    p.BorderStyle = (BorderStyle)p.Tag; // <--- here comes the error
                }
                catch (Exception)
                {

                    
                }
                
            }
        }

2 Ответов

Рейтинг:
2

BillWoodruff

OriginalGriff прав: вы не установили тег; приведение к 'BorderStyle является допустимым. Так что голосуйте за его ответ, а не за этот :)

Я не думаю, что вам нужно перечисление здесь, потому что ... но сначала несколько слов о 'enum:

Все перечисления C# хранят внутреннее значение некоторого числового типа: "утвержденными типами для перечисления являются byte, sbyte, short, ushort, int, uint, long или ulong:" [^].

Когда вы устанавливаете свойство тега элемента управления WinForm, что вы устанавливаете к приводится к объекту (т. е. в штучной упаковке). Если вы зададите ему тип nullable или reference, вы можете получить значение с помощью оператора 'As, что удобно, потому что он вернет 'null, если приведение не сработало. Значение 'enum не является ссылочным типом, не может быть обнулено: поэтому вы не можете использовать 'As.

Теперь о вашем коде: подумайте:

PictureBox pb;

private void PictureBoxes_MouseEnter(object sender, System.EventArgs e)
{
    pb = sender as PictureBox;

    pb.BorderStyle = BorderStyle.Fixed3D;
}

private void PictureBoxes_MouseLeave(object sender, System.EventArgs e)
{
    // you can be sure that 'pb is current here
    if(pb.ImageLocation == null)
    {
        pb.BorderStyle = BorderStyle.None;
    }
}
Затем ваш обработчик событий 'Click упрощает настройку только свойства' ImageLocation при нажатии левой кнопкой мыши вниз.


Рейтинг:
1

OriginalGriff

Скорее всего, где-то вы не установили свойство Tag.
Используйте отладчик, чтобы точно узнать, что находится в теге, когда возникает ошибка: поместите точку останова в оператор catch и посмотрите на p.Tag - если это допустимый стиль границы, то это будет целое число, содержащее 0, 1 или 2. Любое другое значение не поддается кастингу: опорный источник[^]
Как только вы узнаете, что это такое, вы можете посмотреть, почему это так.


ThisandThatorWhat

Извините, не могли бы вы объяснить, где это целочисленное значение появляется из borderstyle. Я знаю, как использовать точку останова и сделать шаг вперед с помощью F11. Кажется, я не могу найти его в локальной или наблюдательной панели, когда подхожу к нему.

ThisandThatorWhat

Я вижу, что значение тега всегда устанавливается в тип строки

ThisandThatorWhat

Я попробовал вручную изменить строку на int, и это работает. Это похоже на то, что свойство tag по умолчанию устанавливает все в строку ? Как я могу изменить то, что очень ценю, спасибо !

OriginalGriff

Нет, тег не имеет значения по умолчанию.
Он содержит объект - что означает все, объявленное как объект, или любой класс, производный от класса объекта. А поскольку **все** в C# в конечном счете является производным от класса object, это означает, что свойство Tag может содержать один экземпляр любого класса, который существует или может быть создан.

Так что вы можете с радостью сделать все это:
мой контроль.Тег = 0;
мой контроль.Тег = 64,9;
мой контроль.Tag = "привет";
мой контроль.Tag = myDataSet;
мой контроль.Тег = объект mybutton;
мой контроль.Тег = это;
мой контроль.Tag = new {Name = "OriginalGriff", Date = DateTime.Сейчас};

(Но это последнее не слишком полезно, если вы не используете динамические переменные позже)