powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / использование BeginInvoke
9 сообщений из 9, страница 1 из 1
использование BeginInvoke
    #36875208
testing22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть экземпляр класса Program. Он:

1. подписан на событие, в котором ему приходят новые данные для обработки. Из этих данных он пользовательским методом формирует таблицу, то есть объект типа DataTable. Реализацию метода я не знаю, просто есть у меня что-то типа myDataTable=GetData(Data), а на выходе имею таблицу с данными.

2. создал окно WPF в новом потоке. В этом окне есть датагрид. В этом датагриде надо отображать эту таблицу сразу при приходе события. То есть каждый раз в пункте 1 эта таблица заполняется новыми данными, которые нужно отобразить.

Как я пытаюсь сделать. Сделал у Program статическое свойство myDataTable, которое используется для биндинга. Сделал тестовый пример, в котором сам создаю и сам заполняю это статическое свойство-таблицу данными, и он работает, но проблема в том, что для того, чтоб он работал мне приходится весь код, относящийся к заполнению таблицы myDataTable, помещать в поток WPF (вообще, хотелось бы этого избежать, то есть просто перезаписывать ссылку на уже готовую myDataTable)

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

Код: plaintext
1.
2.
3.
4.
 MainUI.Dispatcher.BeginInvoke(new ThreadStart(() =>
 {
 myDataTable = как тут сделать, не знаю. myDataTable=GetData(Data) не прокатывает.
 }));

Как можно обновлять myDataTable в гриде в таком случае?
...
Рейтинг: 0 / 0
использование BeginInvoke
    #36875245
AlexeiK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
надо менять случай. а то тут через опу все придумано.

сделай глобальную переменную.
потом своим program классов запиши туда свою mydatatable.
дальше прибинди эту глобалку к гриду .
собственно и все.
при изменении глобалки грид перезальет себя данными.
...
Рейтинг: 0 / 0
использование BeginInvoke
    #36875330
testing22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AlexeiKнадо менять случай. а то тут через опу все придумано.

сделай глобальную переменную.
потом своим program классов запиши туда свою mydatatable.
дальше прибинди эту глобалку к гриду .
собственно и все.
при изменении глобалки грид перезальет себя данными.

Случай да, непростой. Архитектуру придумывал не я. Я пишу ДЛЛ, которая подключается другой прогой, и эта другая прога присылает в мой класс Program это событие с новыми данными. UI там вообще не предусмотрено, а я пытаюсь прикрутить. То есть тут только приспасабливаться.

Вы под глобальной переменной что подразумеваете? Их же вроде не было в C#? Только члены классов, а главный класс у меня меня один - Program.
...
Рейтинг: 0 / 0
использование BeginInvoke
    #36875550
testing22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сделал я такую штуку, в отдельном классе, а не как было раньше, просто статическое свойство в Program:

Код: plaintext
1.
2.
3.
4.
    static public class MyData
    {
        static public DataTable dataTable { get; set; }
    }

Далее код в событии. Для примера я просто заполняю новую таблицу, а потом пытаюсь маршализовать все это дело диспетчеру окна. tblSettings3 - статическое свойство класса Program, тип DataTable. Обработчик события - один из методов Program.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
                MainUI.Dispatcher.BeginInvoke(new ThreadStart(() =>
                {

                    i = i + 1;
                    DataRow dr4 = tblSettings3.NewRow();
                    dr4["Price"] = 222;
                    dr4["Count"] = i;
                    dr4["Comment"] = "Four";
                    tblSettings3.Rows.Add(dr4);
                    DataRow dr5 = tblSettings3.NewRow();
                    dr5["Price"] = 444;
                    dr5["Count"] = 55;
                    dr5["Comment"] = "Five";
                    tblSettings3.Rows.Add(dr5);

                    MyData.dataTable = tblSettings3; //присваиваю ссылку - грид не обновляется. Помоему, собка где-то тут порылась.
                }));

Сам биндинг:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
    public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();

            MyData.dataTable = new DataTable();
            MyData.dataTable.Columns.Add("Price", Type.GetType("System.Int32"));
            MyData.dataTable.Columns.Add("Count", Type.GetType("System.Decimal"));
            MyData.dataTable.Columns.Add("Comment", Type.GetType("System.String"));

            this.DataContext = MyData.dataTable.DefaultView;
        }
     }

При этом, если я напишу в биндинге просто this.DataContext = Program. tblSettings3, а в диспетчере оставлю только код создания таблицы, то все работает. То есть пашет только реальное изменение объекта, который был забинден, в диспетчере окна. У меня есть подозрение, что на датагрид надо биндить метод (формирующий таблицу), но может есть ченить попроще?
...
Рейтинг: 0 / 0
использование BeginInvoke
    #36875652
AlexeiK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
testing22,

ну тут да. я уж и забыл что у тебя datatable ,там же view биндится.
тут придется каждый раз генерить dataview и биндить его .
была бы например obs collection то ее просто биндишь на context и все. а для dt нужно генерить view.
...
Рейтинг: 0 / 0
использование BeginInvoke
    #36875680
testing22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AlexeiK, супер, спасибо, только вот вопрос - а постоянное формирование датафью при биндинге при изменении таблицы, это сильно будет нагружать комп? По сравнению с если бы было все это дело в obs coll, и биндилось разово?

Допускаю, что входная активность будет очень высокой (то есть, несколько таблиц с постоянными изменениями).
...
Рейтинг: 0 / 0
использование BeginInvoke
    #36876266
AlexeiK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
testing22,

ты попробуй и расскажешь.
...
Рейтинг: 0 / 0
использование BeginInvoke
    #36877804
testing22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AlexeiK, попробовал

Проблема в том, что из-за архитектуры приложения, я каждый раз получаю новую Datatable. То есть не изменения, а именно новую. И мне все равно приходится делать кучу телодвижений, а именно, каждый раз, каждый приход данных:

1. Из Datatable забирать данные в список: listDataRow = dataTable.Select().ToList();

2. идти в поток WPF, там вызывать: ObservableCollectionDataRow<DataRow>.Clear(),
(кстати, при очистке наверно тоже срабатывает обновление. Можно как-то запретить обновляться при очистке?)

3. затем по-тупому переводить список listDataRow в ObservableCollectionDataRow:

listDataRow.ForEach(x => ObservableCollectionDataRow.Add(x));

То есть происходит по-существу то же самое что и с датавью. Хотя, на глазок вроде поменьше загрузка.
...
Рейтинг: 0 / 0
использование BeginInvoke
    #36877877
AlexeiK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
testing22,

именно .
других вариантов не будет у тебя.
реализацию можно изменять от одних объектов к другим,но суть та,которую ты описал останется.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / использование BeginInvoke
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]