Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/15: Рейтинг темы: голосов - 15, средняя оценка - 4.73
0 / 0 / 0
Регистрация: 08.12.2015
Сообщений: 6
1

Изменение цвета элемента из другой формы

08.12.2015, 21:22. Показов 2812. Ответов 6
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Создаю некую систему телеметрии и телеуправления. Общение происходит через COM port. Для данного дела надо создать графический интерфейс. Не смотря на очень начальные познания в этом деле, решил реализовать это самостоятельно. С премудростями общения через COM port разобрался, но споткнулся на таком вопросе. На MainWindow.xaml создан квадрат, назвал я его "Т1". В зависимости от поступающего через COM port сообщения этот квадрат должен менять цвет заливки. Для репетиции создал такое
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System.Windows;
using System.Windows.Media;
 
namespace shema01
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        COM_port comm = new COM_port();
        public MainWindow()
        {
            InitializeComponent();
         }
         .............................................
         .............................................  
              
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            T1.Fill = Brushes.Green;
        }
        ..............................................
        ..............................................   
        }
Как и положено, при нажатии на кнопку button1, квадрат Т1 заливается зелёным цветом. Но взаимодействие с COM port организовано в отдельном классе COM_port.cs. Пробую реализовать изменение цвета заливки квадрата Т1 при поступлении в COM_port сообщения "MVT1"
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System.IO.Ports;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Media;
using System.Threading;
 
namespace shema01
{
    
    class COM_port
    {
        SerialPort serialPort1 = new SerialPort();
        serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
      ............................................
      ............................................
     public void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(100);
            string Otvet = "";
            Otvet = serialPort1.ReadExisting();
 
            
            if (Otvet.Contains("MVT1"))
            {
                T1.Fill = Brushes.Green;
 
            }
            serialPort1.DiscardInBuffer();
        }
Естественно, на меня ругается "Имя "Т1" не существует в текущем контексте". Понимаю, что тут ошибка. Класс COM_port.cs даже не подозревает, что существует MainWindow и тем более какой-то квадрат "Т1". Скорее всего в классе COM_port.cs надо как-то объявить объект "Т1". Подскажите как это сделать.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.12.2015, 21:22
Ответы с готовыми решениями:

Изменение цвета одной формы из другой формы
Доброго всем времени суток Очень нужна помощь: необходимо изменить цвет одной формы через другую....

Получение и изменение свойств элемента формы из другой формы
Существует MDI-форма Form1. Форма имеет элемент MainMenu1. Один из пунктов MainMenu1 вызывает...

Изменение цвета в поле формы при совпадении значения поля с аналогичным полем другой
Добрый день! Прошу помочь в решении проблемы. Есть задумка подскажите пожалуйста как реализовать....

Изменение элемента формы из другой формы
Здравствуйте! Подскажите пожалуйста, как из формы1 изменить значение лейбела в форме2. Заранее...

6
Эксперт .NET
1838 / 1346 / 427
Регистрация: 10.06.2011
Сообщений: 2,126
09.12.2015, 17:50 2
Цитата Сообщение от A1000 Посмотреть сообщение
COM_port.cs даже не подозревает, что существует MainWindow и тем более какой-то квадрат "Т1"
Вы абсолютно правы)
Цитата Сообщение от A1000 Посмотреть сообщение
Скорее всего в классе COM_port.cs надо как-то объявить объект "Т1"
Не, не надо объявлять объект "Т1" в COM_port. COM_port - это класс бизнес логики, нафига ему знать о каких-то там квадратах? COM_port будет очень не доволен, если помимо его непосредственных обязанностей его ещё и будут заставлять квадраты раскрашивать. "А потом заборы начнут заставлять красить" - думает COM_port. Пусть вон MainWindow и занимается своими квадратами, раз он их и создаёт.
Вот MainWindow, у него есть квадрат T1. А ещё у него есть COM_port. Вот живёт себе MainWindow, поживает, и думает, как бы ему узнать, когда нужно изменить цвет квадрата? Неплохо было бы, чтобы COM_port сам тыкнул MainWindow, когда нужно. Но как? Конечно же через события.
Создадим событие DataReceived у COM_port:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class COM_port
{
    SerialPort serialPort1 = new SerialPort();
    serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
 
    public void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        Thread.Sleep(100);
        string responce = serialPort1.ReadExisting();
        serialPort1.DiscardInBuffer();
        RaiseDataReceived(responce);
    }
 
    public event EventHandler<DataReceivedEventArgs> DataReceived;
    RaiseDataReceived(string responce)
    {
        var handler = DataReceived;
        if (handler != null)
            handler(this, new DataReceivedEventArgs(responce));
    }
}
 
public class DataReceivedEventArgs : EventArgs
{
    public string Responce { get; private set; }
 
    public DataReceivedEventArgs(string responce)
    {
       Responce = responce;
    }
}
При получении данных из SerialPort'а, инициирует своё событие DataReceived;
А MainWindow пускай подпишется на это событие:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public partial class MainWindow : Window
{
    COM_port comm = new COM_port();
    public MainWindow()
    {
        InitializeComponent();
        comm.DataReceived += comm_DataReceived;
    }
    
    public void serialPort1_DataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Responce.Contains("MVT1"))
        {
            T1.Fill = Brushes.Green;
        }
    }
}
Вот что-то типа того)
0
0 / 0 / 0
Регистрация: 08.12.2015
Сообщений: 6
10.12.2015, 01:33  [ТС] 3
Большое спасибо за ответ. Но при попытке применить Ваш код Visual Studi заругалась в двух местах.
В COM_port на строке 14
C#
1
public event EventHandler<DataReceivedEventArgs> DataReceived;
написало "Метод должен иметь тип возвращаемого значения"
В MainWindow на строке 7
C#
1
comm.DataReceived += comm_DataReceived;
подчеркнуло comm_DataReceived и написало "Имя "comm_DataReceived" не существует в данном контексте"
Скажу честно, с моими познаниями это на грани моего понимания, помогите исправить.

Добавлено через 2 часа 52 минуты
В MainWindow вроде разобрался. 7 строка теперь выглядит так
C#
1
comm.DataReceived += serialPort1_DataReceived;
теперь не ругается.
А вот где грабли в COM_port хоть убей, не пойму. Может кто подскажет?
0
Эксперт .NET
1838 / 1346 / 427
Регистрация: 10.06.2011
Сообщений: 2,126
10.12.2015, 10:02 4
Цитата Сообщение от A1000 Посмотреть сообщение
Скажу честно, с моими познаниями это на грани моего понимания, помогите исправить
Почитайте книжечку Троелсена про C#. Будет легче разобраться.
Цитата Сообщение от A1000 Посмотреть сообщение
В COM_port на строке 14
C#
1
public event EventHandler<DataReceivedEventArgs> DataReceived;
Я код писал прямо здесь в этом окошке, а не в студии. Поэтому за ошибки компиляции не отвечаю. Рассказывал просто об идее. Но если Вы посмотрите на следующую строку, то заметите, что я просто забыл прописать возвращаемый тип у метода RaiseDataReceived. Об этом самом, кстати, Вам и написал компилятор:
Цитата Сообщение от A1000 Посмотреть сообщение
"Метод должен иметь тип возвращаемого значения"
Цитата Сообщение от A1000 Посмотреть сообщение
В MainWindow на строке 7
C#
1
comm.DataReceived += comm_DataReceived;
Метод не правильно назвал. Хотел его назвать comm_DataReceived, но забыл переименовать.

Короче, почитайте вот здесь. Та же книга Троелсена, плюс комментарии и дополнения от товарища Ерохина.
1
0 / 0 / 0
Регистрация: 08.12.2015
Сообщений: 6
12.12.2015, 12:01  [ТС] 5
Что-то я совсем запутался. Исправил ошибки, всё скомпилировалось и запустилось:
MainWindow
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System.Windows;
using System.Windows.Media;
 
namespace shema01
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        COM_port comm = new COM_port();
        public MainWindow()
        {
            InitializeComponent();
            comm.DataReceived += serialPort1_DataReceived; 
         }
         .............................................
         .............................................  
              
        public void serialPort1_DataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e.Responce.Contains("MVT1"))
            {
                T1.Fill = Brushes.Green;
            }
        }
        ..............................................
        ..............................................   
        }
COM_port.cs.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class COM_port
{
    SerialPort serialPort1 = new SerialPort();
    serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
 
        ...................................................
        ...................................................
 
    public void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(100);
            string responce = serialPort1.ReadExisting();
            serialPort1.DiscardInBuffer();
            RaiseDataReceived(responce);
        }
        public event  EventHandler<DataReceivedEventArgs> DataReceived;
        public void RaiseDataReceived(string responce)
        {
            var handler = DataReceived;
            if (handler != null)
                handler(this, new DataReceivedEventArgs(responce));
        }
 
    }
    public class DataReceivedEventArgs : EventArgs
    {
        public string Responce { get; private set; }
 
        public DataReceivedEventArgs(string responce)
        {
            Responce = responce;
        }
Но при отправке в COM port "MVT1" начинает ругаться "Вызывающий поток не может получить доступ к данному объекту, так как владельцем этого объекта является другой поток." Выделяется строка
C#
1
T1.Fill = Brushes.Green;
Что теперь ему не так; Цвет ведь пытаемся изменить из MainWindow которому принадлежит квадрат Т1
0
Эксперт .NET
1838 / 1346 / 427
Регистрация: 10.06.2011
Сообщений: 2,126
12.12.2015, 21:56 6
Не пугайтесь) Всё нормально. Этот код просто выполняется из другого потока. Его нужно вызвать в основном потоке приложения.
C#
1
2
3
4
Application.Current.Dispatcher.Invoke(() =>
{
    T1.Fill = Brushes.Green;
});
1
0 / 0 / 0
Регистрация: 08.12.2015
Сообщений: 6
12.12.2015, 22:45  [ТС] 7
Слава Богу заработало. Большое спасибо за помощь!
0
12.12.2015, 22:45
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.12.2015, 22:45
Помогаю со студенческими работами здесь

Изменение элемента главной формы через другой класс
public class Logger { Form1 f = new Form1(); // Работа с событиями ...

Изменение цвета фона элемента управления формы при запуске процедуры. Запрет на заполнение поля в зав-ти от наличия данных в другом поле
Доброго всем здоровья! Помогите решить проблему! Есть форма &quot;...

Задайте изменение цвета кнопок и цвета шрифта на кнопках формы в ходе выполнения программы
1. Задайте изменение цвета кнопок и цвета шрифта на кнопках формы в ходе выполнения программы. 2....

Изменение цвета формы в зависимости от положения формы по нажатию кнопки
Перерыл весь интернет, до самого не доходит, смысл задания разделить экран на четыре части равных,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru