awaisshabir Ответов: 2

Как Показать панель предупреждающих сообщений в winform?


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

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

public partial class Main : форма
{

public static void DisplayAlert(строковое сообщение, AlertNotification enumAlertNotification)
{
var t = новый таймер();
var main = новый главный();
если (AlertNotification.Успех = = enumAlertNotification)
{

var myControl = новый AlertControl();
myControl.lblMessage.Текстовое сообщение;
мой контроль.Управления.Добавить (myControl.lblMessage);
мой контроль.BackColor = Цвет.Желто-зеленый;
главный.AlertPanel.Управления.Добавить (myControl);
моей воли.Видимое = истинное;
t. интервал = 2000;
t. Tick += (s, e) =>
{
моей воли.Видна = ложь;
Т.Стоп();
};
Т.Начать();
}
если (AlertNotification.Ошибка = = enumAlertNotification)
{
var myControl = новый AlertControl();
myControl.lblMessage.Текстовое сообщение;
мой контроль.Управления.Добавить (myControl.lblMessage);
мой контроль.Цвет Фона = Цвет.Красный;
главный.AlertPanel.Управления.Добавить (myControl);
моей воли.Видимое = истинное;
t. интервал = 3000;
t. Tick += (s, e) =>
{
моей воли.Видна = ложь;
Т.Стоп();
};
Т.Начать();

}
если (AlertNotification.Информация = = enumAlertNotification)
{
var myControl = новый AlertControl();
myControl.lblMessage.Текстовое сообщение;
мой контроль.Управления.Добавить (myControl.lblMessage);
мой контроль.BackColor = Цвет.Светло-голубой;
главный.AlertPanel.Управления.Добавить (myControl);
моей воли.Видимое = истинное;
t. интервал = 3000;
t. Tick += (s, e) =>
{
моей воли.Видна = ложь;
Т.Стоп();
};
Т.Начать();

}
}


}

// я вызываю эти строки кода в пользовательском контроле

Главный.DisplayAlert (строка.Формат("{0} {1}",TotalsCount,"Найденные Записи"), AlertNotification.Информация);

// ниже приведен мой код управления предупреждением пользователя

общественный разделяемого класса AlertControl : элемент управления UserControl
{
частная марка _lblMesage;

публичная метка lblMessage
{
получить
{
если (_lblMesage == нуль)
_lblMesage = новая метка();
вернуться _lblMesage;
}

}
общественные AlertControl()
{
это.lblMessage.Авторазмер = истина;
это.lblMessage.BackColor = Система.Рисование.Цвет.Прозрачный;
это.lblMessage.Шрифт = новая система.Рисование.Шрифт ("Century Gothic", 9.75 F, System.Рисование.Стиль шрифта.регулярная система.Рисование.GraphicsUnit. Point, ((байт) (0)));
это.lblMessage.Местоположение = новая система.Рисование.Точка (36, 7);

это.lblMessage.Размер = новая система.Рисование.Размер (188, 17);
это.lblMessage.TabIndex = 0;

метод InitializeComponent();
}
}

Philippe Mori

Используйте блок кода для вашего кода. Вы не получите большой помощи с неформатированным кодом. Никто не любит это читать.

2 Ответов

Рейтинг:
1

BillWoodruff

Вы можете изменить родительский элемент управления элемента управления или UserControl, просто добавив его в коллекцию ControlCollection элемента управления / Usercontrol, который вы хотите сделать "новым" родителем. По сути, операция ' Add удаляет элемент управления / UserControl из его текущей родительской коллекции ControlCollection, а затем вставляет его в новую коллекцию ControlCollection.

Ли вы должен изменить родителя элемента управления/пользователя?Контроль во время выполнения-это другой вопрос, и я считаю, что вам следует избегать этого, если только для этого нет очень веской причины.

Как я понимаю ваш вопрос, то, что вы хотите сделать здесь, не показывает эту панель предупреждений внутри произвольного элемента управления вашей формы, но вы действительно хотите показать ее поверх и рядом с одним из элементов управления вашей формы. Я покажу вам код, который может это сделать, но ... первый... несколько замечаний о наследовании Control/UserControl::

Один пример элемент управления, или UserControl, расположенный в добавлена-в в экземпляре коллекции controlcollection экземпляра формы, или другие ContainerControl, имеет доступ к контроля/форма он был добавлен, чтобы через ее родителя собственность, ее TopLevelControl Propertry будет возвращать внешние-самые (топ-уровня) - контроля (ContainerControl), в которой он содержится.

Предположим, что у вас есть 'Panel2 с 'Button3 внутри него, а Panel2 находится внутри Panel1, который находится внутри Form1:

private void Form1_Load(object sender, EventArgs e)
{
    var parent = button3.Parent;   // => Panel2
    var toplvl = button3.TopLevelControl; // => Form1

    var inheritance = button3.GetControlInheritance().ToList(); // => see below
}
Метод ' GetControlInheritance является методом расширения:
public static class ControlExtensions
{
    public static IEnumerable<Control> GetControlInheritance(this Control control)
    {
        while (control.Parent != null)
        {
            yield return control.Parent;
            control = control.Parent;
        }
    }
}
И результат его вызова в этом примере таков: & lt;Panel2, Panel1, Form1>

Теперь предположим, что у вас есть панель (или UserControl), которую вы хотите использовать в качестве "оповещения." Это называют 'AlertPanel. Предположим, что существует какое-то событие, которое вы обрабатываете с помощью метода, который получает ссылку на элемент управления, который вы хотите отобразить рядом с AlertPanel, причем левая верхняя часть AlertPanel смещена на 10,10 пикселей от левой верхней части элемента управления, который вы хотите отобразить "над"."

1. вы помещаете панель (или UserControl) в форму, устанавливаете ее "видимое свойство" в значение "false".

2. допустим, ваш обработчик событий выглядит следующим образом:
private void ShowAlertPanel(Control toShowOver, int offx, int offy)
{
    Point loc = toShowOver.Location;
    loc.Offset(offx,offy);
    AlertPanel.Location = loc;
    
    AlertPanel.BringToFront();
    AlertPanel.Show();
}
3. но есть еще одно возможное требование: что делать, если вы хотите показать свою панель AlertPanel над элементом управления, вложенным в другой элемент управления. Поскольку местоположение этого вложенного элемента управления находится в координатах, основанных на его родительском элементе управления, вы должны сначала сопоставить координаты вложенного элемента управления с координатами экрана, а затем сформировать координаты. Что впрочем совсем не сложно, :
private void ShowAlertPanel2(Control toShowOver, int offx, int offy)
{
    if (toShowOver == this) throw new ArgumentException("Cannot use Form Parent");

    Point loc = toShowOver.Location;

    // handle showing over nested Control
    if (toShowOver.Parent != this)
    {
        // get screen location
        loc = toShowOver.Parent.PointToScreen(loc);

        // translate it to Form co-ordinates
        loc = this.PointToClient(loc);
    }

    loc.Offset(offx,offy);
    AlertPanel.Location = loc;

    AlertPanel.BringToFront();
    AlertPanel.Show();
}


Рейтинг:
1

Dave Kreskowiak

"Главный.DisplayAlert " ничего не будет делать, потому что элементы управления/usercontrols вообще ничего не должны знать о форме, в которой они находятся, и им вообще все равно. Если вы попытаетесь сделать это, вы навсегда свяжете эти две формы/элементы управления вместе. Они никогда не могут быть разделены и использованы независимо.

Ваш DisplayAlert вообще не должен быть в основной форме. Если вы собираетесь попробовать использовать его из любого места вашего приложения, это должен быть его собственный класс со статическим методом ShowAlert, который создает форму оповещения, устанавливает ее свойства и показывает форму.


BillWoodruff

"элементы управления / usercontrols вообще ничего не знают о форме, в которой они находятся"

Я почтительно прошу вас не согласиться; пожалуйста, посмотрите мой пост здесь.

Dave Kreskowiak

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

Если форма реализует интерфейс и элемент управления успешно перемещается по своей родительской цепочке до этого интерфейса, хорошо, это допустимо. Не великое, но допустимое. Проблема в том, что каждая форма, на которую помещается элемент управления, должна реализовывать ожидаемый интерфейс.

Если мы показываем диалог оповещения над родительской формой или вокруг нее, я бы, вероятно, реализовал это как статический класс/метод, который принимает элемент управления, бросающий предупреждение в качестве параметра, перемещается по родительской цепочке управления, чтобы получить форму, получить ее координаты и размер и соответствующим образом показывает сообщение оповещения в новом диалоговом окне.

Элементы управления никогда не должны ничего знать о форме, элементах управления или коде, который предоставляет их родительская цепочка, как предполагает фрагмент кода OP posted. Он связывает элемент управления с формами, ограничивает повторное использование элементов управления, и если кто-то еще хочет использовать элемент управления, он должен знать о том, что элемент управления ожидает от формы.

BillWoodruff

Это хорошая проповедь, и я также являюсь последователем "веры в инкапсуляцию", но в данном случае она на самом деле не связана с кодом операции и вопросами. Вы заметили, что ОП здесь использует UserControl, расположенный на форме ? Это не тот сценарий, в котором возникают проблемы с использованием 'ShowDialog.

Похоже, вы совершенно упустили смысл моего комментария/поста. Элемент управления, или UserControl, по своей конструкции, как я покажу в своем ответе ниже, предоставляет доступ к своему родителю и его контейнеру верхнего уровня через свойства 'Parent и 'TopLevelControl.

Microsoft предоставляет эти свойства по уважительной причине, и задача этого пользователя, как я вижу, заключается в использовании этих свойств.

Обратите внимание, что мое решение показывает только элемент управления/UserControl, которым манипулирует форма its on; нет никакой манипуляции формой с помощью элемента управления/UserControl, который вы, кажется, считаете здесь опасным. Только форма делает использование TopLevelControl и родительские свойства.

Dave Kreskowiak

Я ведь правильно поняла. Мы оба спорим на одной стороне. Я испортил свой первоначальный пост и исправил его.

BillWoodruff

"Ваш DisplayAlert не должно быть на главной вообще форма"."то, что создает форму оповещения "

Извини, Дэйв, но твой пост все еще очень запутан. ОП вот с помощью пользовательских элементов управления, а не форма.

У меня нет другого выбора, кроме как проголосовать против этого очень запутанного и вводящего в заблуждение ответа.

Dave Kreskowiak

В его код пользовательского элемента управления он имеет вызова main.DisplayAlert () - это метод, который он поместил в основную форму. Не понимаю, что тут такого непонятного.