вторник, 16 августа 2016 г.

c# wpf. Доступ к элементам формы из стороннего класса

Visual Studio 2012 (WPF)

Создание часов на форме.

Для доступа к элементу UI главного окна TextBox из стороннего класса создадим в отдельном статическом классе Consts.cs (public static class Consts) структуру:
public struct Rect
        {
            public System.Windows.Threading.Dispatcher dm; //Поток главного окна
MainWindow 
            public System.Windows.Controls.TextBox tb1; //MainWindow TextBox tb1
        }

В этой структуре можно описать все элементы формы.

Создадим сторонний класс:
using System.Threading;
using System.Windows.Threading;


public class Class1
    {
        public bool StopThread { get; set; } //Остановить фоновый поток
        public
Consts.Rect par { get; set; } //Ссылка на структуру главной формы (par - параметры)

        public void Start()
        {
            Thread1();
        }

        private void Thread1() //Организация фонового потока
        {
            ThreadStart start1 = delegate()
            {
                while (!StopThread) //При закрытии формы изменить на true и остановить поток
                {

                    //Вместо Dispatcher.BeginInvoke пишем так:
                    par.dm.BeginInvoke(new ThreadStart(delegate
                    {

                         //На главной форме отображать дату и время:
                         par.tb1.Text = DateTime.Now.ToString(); 
                    }));
                    Thread.Sleep(1000); //Задержка на 1 секунду
                }
            };
            new Thread(start1).Start();
        }
    }

Класс главной формы:
public partial class MainWindow : Window
    {

        Class1 cl = new Class1(); //Объявляем класс фонового потока

        //После показа окна:
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Consts.Rect par;
            par.dm = this.Dispatcher; //Передача потока главной формы
            par.tb1 = this.tb1; //Ссылка на изменяемый в фоне TextBox
            cl.par = par; //Передаем параметры

            cl.StopThread = false; //Фоновый поток будет работать
            cl.Start();
        }


         //Контрольная кнопка на форме для демонстрации возможности работы в форме:
        private void bt1_Click(object sender, RoutedEventArgs e)
        {
            tb2.Text = tb1.Text; //При нажатии кнопки, вывести текст в другой TextBox
        }


        //При закрытии формы остановить поток:
        private void Window_Closed(object sender, EventArgs e)
        {
            cl.StopThread = true;
        }

    }

PS А можно в MainWindow.xaml прописать наименование формы:
Title="MainWindow" Height="350" Width="525"
Name="mWindows"
и использовать его в стороннем классе:
public MainWindow mw { get; set; }
но это не по-варварски :)

пятница, 15 мая 2015 г.

C# WPF. Создать TreeView из базы MySQL с несколькими уровнями узлов

Table1: 'id'-int, 'pid'-int (parent), 'sName'-string
1,0,"itm1"
2,1,"itm2"
3,2,"itm3"

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using MySql.Data.MySqlClient; //MySql.Data.dll
using System.Data;

namespace _WpfApp
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private MySqlConnection conn;
        private MySqlCommand selectCommand;
        private MySqlDataReader reader;
        private DataTable dt;

        private void mn(string s)
        {
            if (s == "Определить параметры подключения к БД") cnBD();
            if (s == "Прочитать из БД в поток") setMySQL2reader();
            if (s == "Локальная БД для TreeView") LocBD2TreeView();
            if (s == "Очистить TreeView") TreeView1.Items.Clear();
            if (s == "Заполнить TreeView из локальной БД") setTreeView(null, "0");
        }

        public MainWindow() //Куда уж без тебя
        {
            InitializeComponent();
        }
       
        private void cnBD() //Определить параметры подключения к БД
        {
            string cn = "server=localhost; user id=%user%; password='%password%'; database=test";
            conn = new MySqlConnection(cn);
            conn.Open();
        }

        private void setMySQL2reader() //Прочитать из БД в поток
        {
            string mySelectQuery = "SELECT id, pid, SName FROM table1";
            selectCommand = new MySqlCommand(mySelectQuery, conn);
            reader = selectCommand.ExecuteReader();
        }

        private void LocBD2TreeView() //Локальная БД для TreeView
        {
            dt = new DataTable("dtTree");
            dt.Columns.Add("id", typeof(int));
            dt.Columns.Add("pid", typeof(int));
            dt.Columns.Add("sName", typeof(string));

            while (reader.Read())
            {
                dt.Rows.Add(reader.GetInt32("id"), reader.GetInt32("pid"), reader.GetString("sName"));
            }

            selectCommand.Connection.Close();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            mn("Определить параметры подключения к БД");
            mn("Прочитать из БД в поток");
            mn("Локальная БД для TreeView");
            mn("Очистить TreeView");
            mn("Заполнить TreeView из локальной БД");
        }

// Собственно ради чего заметка писалась:
        private void setTreeView(TreeViewItem parItem, string parent) //Заполнить TreeView из локальной БД
        {
            foreach (DataRow dr in dt.Rows)
            {
                if (dr["pid"].ToString() == parent)
                {
                    TreeViewItem chItem = new TreeViewItem();
                    chItem.Header = dr["sName"].ToString();
                    setTreeView(chItem, dr["id"].ToString()); //Рекурсия
                    if (parItem == null & parent == "0") TreeView1.Items.Add(chItem); //TreeView root-Header
                    else parItem.Items.Add(chItem);
                }
            }
        }
    }
}

среда, 22 апреля 2015 г.

C# WPF. Создать TreeView с несколькими уровнями узлов


Простой пример создания TreeView с несколькими уровнями.
Использую http://professorweb.ru

foreach (System.IO.DriveInfo drive in System.IO.DriveInfo.GetDrives())
            {
                TreeViewItem item = new TreeViewItem();
                item.Header = drive.ToString();

                //Вместо подключения подуровня
                //item.Items.Add("1");
                //TreeView1.Items.Add(item);
                //Создам ещё один узел:

                TreeViewItem newItem = new TreeViewItem();
                newItem.Header = "1";
                newItem.Items.Add("2");
                item.Items.Add(newItem);
                TreeView1.Items.Add(item);
            }

понедельник, 21 февраля 2011 г.

Godex BZB-2 (EZ-2) и 1C8.x

Дано:
Windows XP professional
1С8.0 (Управление торговлей)
Godex BZB-2/EZ-2

Проблема:
При печати этикеток сбивается настройка печати принтера шрихкода, или край этикетки постоянно сбивается.

Перед установкой  принтера этикеток удалим все имеющиеся принтера, для этого
  • Останавливаем службу "Диспетчер очереди печати"
  • Удаляем все содержимое каталога C:\Windows\system32\spool\PRINTERS, это место хранения неотработанных заданий на печать (.shd и .spl)
  • Запускаем службу "Диспетчер очереди печати" и удаляем все установленные принтеры
  • Останавливаем службу "Диспетчер очереди печати"
Удаляем сохраненные драйвера принтеров и их настройки (C:\Windows\system32\spool), удаляем все что получится (за исключением ниже перечисленного), перезагружаемся и удаляем оставшееся, на время удаления естественно останавливаем "Диспетчер очереди печати".
  • В каталоге C:\Windows\system32\spool остаются только папки drivers и PRINTERS
  • В каталоге C:\Windows\system32\spool\drivers остаются только папки color и w32x86
  • В каталоге  C:\Windows\system32\spool\drivers\w32x86 может остаться пустая папка 3
Запускаем "Диспетчер очереди печати", теперь он нам понадобится.

Устанавливаем драйвер EZ_BZB_drivers_v2.0_vista.rar (http_://www.scancode.ru/files/item/3/207/)


Зайдя в "Свойства принтера" во вкладке "Общие" найдем "Настройку печати" на вкладке "Paper" видим, что доступны для выбора форматы бумаги "Зарезервировано 48", "Зарезервировано 49" и "Label 2 x 4in". Первые два созданы самой системой, и изменить их невозможно (прописаны в файле system32\localspl.dll), последний создан в реестре "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Forms".

Для работы с этикет-лентой 20x30мм создадим формат страницы:
WinXP: "Пуск-Настройка-Принтеры и факсы"
 Vista, Win7: "Пуск-Панель управления-Администрирование-Управление печатью-Сервер печати-Формы".

Далее "Свойства принтера-Настройка печати":
Установим Units= "0.1 mm", Paper Sensing = "Paper Gap/Tag", Label Gap = "10", желательно Print Speed уменьшить до 1.

К сожалению, 1С8.x при печати игнорировал пользовательские настройки и все сбрасывал в Default. Поэтому изменим Default.
Пользовательские настройки дублируются в двух REG_BINARY параметрах реестра: "HKEY_CURRENT_USER\Printers\DevModePerUser\Godex EZ-2 203dpi" и "HKEY_CURRENT_USER\Printers\DevModes2\Godex EZ-2 203dpi", а настройки по-умолчанию также в двух "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Printers\Godex EZ-2 203dpi\Default DevMode" и "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Printers\Godex EZ-2 203dpi\PrinterDriverData\DevmodeData", копируем содержимое любого из пользовательских параметров в параметры по-умолчанию.