Т.к. на форумах MSDN буквально за последние 24 часа задают практически один и тот же вопрос дважды (тык и тык), то давайте я напишу небольшой пример. Под катом первая форма, создаст вторую форму и будет управлять ей и узнавать о событиях там происходящих. Пример простой, но надеюсь наглядный.
1. В пустой WPF проект добавляем второе окно. Даем ему имя SecondWindow. На этом окне будет компонент для ввода данных и кнопка отправить. Если то что ввели является числом, то по нажатию на кнопку "Отправить" текст будет зеленеть, если нет, то краснеть. Для этого на форму размещаем следующую разметку:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SecondWindow" SizeToContent="WidthAndHeight">
<StackPanel Orientation="Horizontal">
<TextBox x:Name="tbInput" Width="150" Margin="5" />
<Button Content="Отправить" Margin="5" Click="Button_Click" />
</StackPanel>
</Window>
2. В коде страницы объявляем событие, через которое мы будем отправлять уведомление о нажатии кнопки и подготовленном тексте в главную форму:
3. В эту же форму добавляем метод раскраски текста:
4. Ну и обработчик клика на кнопке:
На этом со второй формой все. Как видно, у нее нет никакой логики для принятия решения о покраске текста. Только уведомление об окончании ввода и раскраска в зависимости от переданного параметра. Всю логику мы соберем на главной форме. XAML на ней править не буду, только код.
5. В код главной формы добавляем поле для хранения ссылки на вторую форму:
6. Добавляем метод принимающий решение о введенном на второй форме тексте и уведомляющий ее о принятом решении:
7. Ну и правим конструктор формы и пишем метод обслуживающий событие Loaded, для создания второго окна и подписывания предыдущего метода на событие второй формы.
8. Запускаем, главная форма сразу после запуска показывает вторую и вводя в ней разные значения мы можем нажимая кнопку Отправить получать разный цвет текста:
Все, главная форма может влиять на дочернюю, а дочерняя передавать по своей инициативе данные главной для обработки.
1. В пустой WPF проект добавляем второе окно. Даем ему имя SecondWindow. На этом окне будет компонент для ввода данных и кнопка отправить. Если то что ввели является числом, то по нажатию на кнопку "Отправить" текст будет зеленеть, если нет, то краснеть. Для этого на форму размещаем следующую разметку:
<Window x:Class="WpfApplication6.SecondWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SecondWindow" SizeToContent="WidthAndHeight">
<StackPanel Orientation="Horizontal">
<TextBox x:Name="tbInput" Width="150" Margin="5" />
<Button Content="Отправить" Margin="5" Click="Button_Click" />
</StackPanel>
</Window>
2. В коде страницы объявляем событие, через которое мы будем отправлять уведомление о нажатии кнопки и подготовленном тексте в главную форму:
public event Action<string> TextEntered; protected void OnTextEntered(string p_text) { var handler = TextEntered; if (handler != null) { handler(p_text); } }
3. В эту же форму добавляем метод раскраски текста:
public void ConfirmNumber(bool p_isConfirm)
{
if (p_isConfirm)
{
tbInput.Foreground = new SolidColorBrush(Colors.Green);
}
else
{
tbInput.Foreground = new SolidColorBrush(Colors.Red);
}
}
private void Button_Click(object sender, RoutedEventArgs e) { OnTextEntered(tbInput.Text); }
5. В код главной формы добавляем поле для хранения ссылки на вторую форму:
private SecondWindow _second;
6. Добавляем метод принимающий решение о введенном на второй форме тексте и уведомляющий ее о принятом решении:
private void CheckText(string p_text) { int x; var result = false; if (int.TryParse(p_text, out x)) { result = true; } _second.ConfirmNumber(result); }
public MainWindow() { InitializeComponent(); Loaded += MainWindow_Loaded; } void MainWindow_Loaded(object sender, RoutedEventArgs e) { _second = new SecondWindow(); _second.TextEntered += CheckText; _second.Show(); }
8. Запускаем, главная форма сразу после запуска показывает вторую и вводя в ней разные значения мы можем нажимая кнопку Отправить получать разный цвет текста:
Все, главная форма может влиять на дочернюю, а дочерняя передавать по своей инициативе данные главной для обработки.
И спасибо за Ваше внимание и ответ, а-то я было разочаровался в DevNetwork
ОтветитьУдалитьНи очаровываться, ни разочаровываться смысла нет... Отвечающих мало, но когда у них есть возможность помочь, помогают.
УдалитьСмысл в том, что Microsoft разработала C#, разработала Visual Studio, и начинающему программисту кажется, что у разработчика будет наилучшая поддержка своих продуктов (не только MSDN), платформа для обсуждений/советов, bestpractice.
УдалитьНу да, только вот все то что вы рассказываете очень хорошо работает на английском языке. Пока русскоговорящих покупателей не будет примерно столько-же, сколько и англоговорящих, русский MSDN будет переводиться по остаточному принципу, ответы на форуме будут только парой-тройкой энтузиастов комьюнити...
УдалитьПодключусь к комьюнити :)
УдалитьЯ реализовал немного по другому(коллеги подсказали)
ОтветитьУдалитьУ второго окна создал свойство
public MainWindow MainWindow { get; set; }
В MainWindow
Создаю тред
Thread NotifyThread = new Thread(() => {
NotificationWindow Toast = new NotificationWindow();
Toast.Show();
Toast.MainWindow = this;
Toast.Closed += (sender2, e2) => { Toast.Dispatcher.InvokeShutdown(); };
System.Windows.Threading.Dispatcher.Run();
}
);
NotifyThread.SetApartmentState(ApartmentState.STA);
NotifyThread.Start();
Теперь во втором окне
toasty.MouseLeftButtonDown += (obj, arg) => this.MainWindow.ShowToast(((System.Windows.Controls.TextBlock)obj).Text);
Отрабатывается метод ShowToast главного окна
public void ShowToast(String text) {
this.Dispatcher.Invoke((Action)(() =>
{
tick.Text = text;
}));
}
Единственное, у меня теперь такая задачка, т.к. главное окно Maximized,то как создать второе окно, чтобы не показывался taskbar? Как-то на фоне fullscreen приложения появляющийся taskbar портит целостное впечатление
У вашего подхода есть небольшое нарушение парадигм ООП. У вас главное окно имеет ссылку на всплывающее, а всплывающее на главное. Т.е. если вы захотите готовое всплывающее окно перенести в другой проект, а главная форма будет там с другими полями/методами, то вам придется код менять. В предложенном мной подходе, дочернее окно ничего не знает о главном и может быть вынесено в отдельную сборку и без переделываний использоваться в других проектах, где, например, текст будет проверяться не на приведение к числу, а на количество слов или еще что-нибудь
Удалить