Ежедневник IT-ка
133 subscribers
22 photos
4 videos
1 file
43 links
Программируем на практике!!
По вопросам по поводу проектов: @vladimir_dzen
Download Telegram
❗️Внимание. Для тех, кто разрабатывает проекты используя WPF.

XAML Behaviors для WPF теперь Open Source.

В прошлом году мы открыли исходный код XAML Behaviors для UWP, который имел большой успех, и пакет Behaviors NuGet был загружен более 500 000 раз. XAML Behaviors для WPF теперь поставляется в виде пакета NuGet — Microsoft.Xaml.Behaviors.Wpf. Подробнее под катом!

Это позволит быстрее добавлять новые фичи и исправлять ошибки. Когда новый Behavior или фича добавляется в репозиторий, их можно будет использовать практически сразу. Открытость для исправлений позволяет платформе Behaviors развиваться, предоставляя сообществу возможность задавать темп и направление. Хотя вы можете продолжать использовать Extension SDK, дальнейшая разработка будет осуществляться только на GitHub и будет опубликована в пакете NuGet в новом пространстве имен Microsoft.Xaml.Behaviors.

ссылка на полную статью.

#Csharp,#WPF,#XAML
​​Рефлексия - это процесс, который позволяет программе изучать саму себя.
Звучит довольно интересно и интригующе, в практике позволяет:
- перечислять члены типа
- извлекать информацию о типе
- извлекать информацию о сборке
- исследовать пользовательские атрибуты
Надо понимать, что это всё применимо для общедоступных (public) методов из заданного типа.

Рассмотрим простой пример(реализован в WPF приложение):

1. Создаём объект класса(это отдельный файл с расширением .cs).

namespace HumanizerDemo
{
  public class Binance
  {
    public int BalanceUSD { get; set; }
    public int BalanceBTC { get; set; }
    public Binance(int n, int a)
    {
      BalanceUSD = n;
      BalanceBTC = a;
    }

    public int CalculateCount(int countUsd, int priceBtc)
    {
      return countUsd / priceBtc;
    }
  }
}

2. При создание проекта WPF автоматически создаётся файл MainWindow.xaml с разметкой(это, то что у меня):

<Window x:Class="HumanizerDemo.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:HumanizerDemo"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
  <Grid>

  </Grid>
</Window>

2.1. В этот код добавляем:

- элемент компоновки "StackPanel",
- текстовый элемент "TextBlock",
- элемент кнопки "Button"

  <Grid>
    <StackPanel>
      <Button Name="GetHumanMethodNames" Click="GetHumanMethodNames_OnClick">Получение методов</Button>
      <TextBlock Name="Output"></TextBlock>
    </StackPanel>
  </Grid>

Продолжение следует...

#Рефлексия, #Csharp, #WPF
​​Продолжаю писать статьи связанные с созданием приложения используя WPF. Даю ссылку на свой прошлый пост, где касался слегка этой темы.

Планирую написать ряд статей по созданию приложения, которое отсылает текстовые сообщения в ТГ(телеграм), используя его API.

Почему? Потому что, написания приложений используя API ТГ в "тренде" и полагаю он ещё будет долгое время.

В этой части статьи покажу весь код XAML файла, который реализовал т.е. интерфейс самой программы.

Основной код:

<Window x:Class="TelegramBot.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:TelegramBot"
    mc:Ignorable="d"
    Title="MainWindow" Height="150" Width="800">
  <DockPanel LastChildFill="True">
<Menu DockPanel.Dock="Top"> 
      <MenuItem Header="Данные">
        <MenuItem Header="Сохранить"
             Command=""/>
        <Separator/>
        <MenuItem Header="Выход"
             Click="MenuItem_Click"/>
      </MenuItem>
    </Menu>
    <ListView DockPanel.Dock="Left"
         Background="MidnightBlue"
         Width="140">
      <TextBlock Text="Новое сообщение:" Foreground="White"/>
    </ListView>
    <StatusBar DockPanel.Dock="Bottom">
      <StatusBar.ItemsPanel>
        <ItemsPanelTemplate>
          <Grid>
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="Auto" />
              <ColumnDefinition Width="Auto" />
              <ColumnDefinition Width="Auto" />
              <ColumnDefinition Width="Auto" />
              <ColumnDefinition Width="100" />
              <ColumnDefinition Width="Auto" />
              <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
          </Grid>
        </ItemsPanelTemplate>
      </StatusBar.ItemsPanel>
      <StatusBarItem>
        <TextBlock Text="Статус:" />
      </StatusBarItem>
      <Separator Grid.Column="1" />
      <StatusBarItem Grid.Column="2">
        <TextBlock Text="Не отправлено" />
      </StatusBarItem>
      <Separator Grid.Column="3" />
      <StatusBarItem Grid.Column="4">
        <TextBlock Text="Кол-во знаков:" />
      </StatusBarItem>
      <Separator Grid.Column="5" />
      <StatusBarItem Grid.Column="6">
        <TextBlock Text="259" />
      </StatusBarItem>
    </StatusBar>
    <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="5*"/>
        <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>
      <TextBox Grid.Column="0" AcceptsReturn="True" VerticalScrollBarVisibility="Auto"
     HorizontalScrollBarVisibility="Auto"/>
    <Button Grid.Column="1" x:Name="buttonSentMessage" Width="60" Height="30" Content="Нажать" Click="Button_Click" />
    </Grid>
  </DockPanel>
</Window>

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

В результате создания приложения этот код будет корректироваться.

#WPF, #Csharp
​​Рассматриваю более детальнее код, который опубликовал в прошлой статье.

1. Это часть кода генерируется автоматически в которой объявляются пространства имён.

<Window x:Class="TelegramBot.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  xmlns:local="clr-namespace:TelegramBot"
  mc:Ignorable="d"
  Title="MainWindow" Height="150" Width="800">

Мне интересна, в данном случае, вот эта строка, где указываем размеры формы приложения:

" Title="MainWindow" Height="150" Width="800"

2. Контейнер DockPanel - его очень удобно использовать для создания стандартных интерфейсов.

Верхнюю и левую часть - можно использовать для меню.

Нижнюю часть - для отображение какой-то доп информации(чаще строка состояния, в сайтостроении называют также эту часть "подвал").

Правую часть - для отображения дополнительной части.

Центр - здесь находится основное содержание.

<DockPanel LastChildFill="True">
..................
..................
..................
 </DockPanel>

Свойство LastChildFill="True" означает, что последний элемент(в нашем случае, это текстовое поле "TextBox" и кнопка "Button") заполняет всё оставшееся пространство. 

3. Элемент управления Menu (выделяю его специально, т.к. в него входят другие элементы) - который расположен в верхней части нашей DockPanel панели.

<Menu DockPanel.Dock="Top"> 
   <MenuItem Header="Данные">
    <MenuItem Header="Сохранить"
       Command=""/>
    <Separator/>
    <MenuItem Header="Выход"
       Click="MenuItem_Click"/>
   </MenuItem>
  </Menu>

3.1. <MenuItem Header="Данные"> - это название меню. Оно может состоять из нескольких т.е. :

<MenuItem Header="Данные">
<MenuItem Header="Сохранить">
<MenuItem Header="Выход"">

3.2. Свойство "Command" используется для паттерна MVVM(Model-View-ViewModel). О нём буду говорить, в других постах, если будет необходимо.

3.3. Элемент  <Separator/> - это понятно, "разделитель".

3.4. Событие Click="MenuItem_Click" с присвоенным ему именем. Оно будет обрабатываться в коде.

Продолжение следует....

#WPF, #Csharp
​​Продолжаю знакомить с WPF.
В предыдущем посте остановился на рассмотрении элемента управления "Menu".

В этом рассмотрю сразу несколько элементов управления(кратко) "ListView", "TextBlock", "StatusBar" и "Grid"

1. Часть кода, который буду рассматривать.

<ListView DockPanel.Dock="Left"
         Background="MidnightBlue"
         Width="140">
      <TextBlock Text="Новое сообщение:" Foreground="White"/>
    </ListView>
    <StatusBar DockPanel.Dock="Bottom">
      <StatusBar.ItemsPanel>
        <ItemsPanelTemplate>
          <Grid>
            <Grid.ColumnDefinitions>
              ..................
              ..................
             ..................
            </Grid.ColumnDefinitions>
          </Grid>
        </ItemsPanelTemplate>
      </StatusBar.ItemsPanel>
..................
   ..................
   ..................
    </StatusBar>

2. Элемент управления ListView(главный элемент в нашем интерфейсе), расположен в левой части интерфейса DockPanel.Dock="Left". Не смотря на то, что он унаследован от класса другого элемента ListBox, является более "продвинутым" т.к. ещё можно добавлять "заголовки столбцов" т.е. у него есть свойство "View", которое имеет свой элемент(объект) GridView, который позволяет создавать более сложную структуры таблицы(со своими названиями столбцов)

2.1. Короткий пример(добавление "Заголовков " столбцов т.е. "Headers"):

<ListView.View>
   <GridView>
      <GridViewColumn>№</GridViewColumn>
<GridViewColumn>Кол-во штук</GridViewColumn>
<GridViewColumn>Цена</GridViewColumn>
   </GridView>
</ListView.View>

2.2. Элемент управления TextBlock - служит для вывода текстовой информации и имеет свойство Foreground="White". В котором устанавливается цвет, переднего фона элемента, в нашем случае "цвет текста".

3. Переходим к след. элементу управления StatusBar (главный элемент в нашем интерфейсе), располагается в нижней части интерфейса DockPanel.Dock="Bottom".

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

3.1. Обратимся к свойству ItemsPanel у элемента StatusBar т.е. <StatusBar.ItemsPanel>

3.2. Далее обратимся к элементу ItemsPanelTemplate, который будет в какой-то степени отвечать за оформления нашего StatusBar.

Элемент ItemsPanelTemplate, необходимо будет использовать довольно часто при работе с WPF.

3.3. В ItemsPanelTemplate добавляем такой элемент управления, как Grid

Grid - ЭТО мощный и часто используемый контейнер, напоминающий обычную таблицу. Прошу запомнить это т.к. без него интерфейс напоминал "беспорядочность".

3.3.1. Элемент Grid имеет два интересных свойств:

а) <Grid.ColumnDefinitions> - для работы с размерами столбцов - шириной.
б) <Grid.RowDefinitions> - для работы с размерами столбцов - высотой.

На этом всё.

Продолжение следует.....

#WPF#Csharp
​​Продолжаю знакомство с WPF.
В прошлой статье остановился на рассмотрение такого элемента как Grid.

Одно из важных свойств этого элемента(и не только этого) ширина и высота.
Есть несколько вариантов установки размеров:
"Auto" - установка ширины элемента согласно его содержанию.
"100" - фиксированный размер.
"*" - пропорциональный размер(маленький лайфхак, хотите увеличить этот размер в 2 в 3 раза, просто сделайте запись таким образом "2*" или "3*" ).

Для того, чтобы необходимый элемент имел правильные очертания(в моём случае это элемент "Grid"), то рекомендуется комбинировать эти размеры по необходимости.

          <Grid>
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="Auto" />
              <ColumnDefinition Width="Auto" />
              <ColumnDefinition Width="Auto" />
              <ColumnDefinition Width="Auto" />
              <ColumnDefinition Width="100" />
              <ColumnDefinition Width="Auto" />
              <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
          </Grid>

Завершаем знакомство с элементами ItemsPanelTemplate и StatusBar.ItemsPanel - которые отвечали за основное оформление(т.е. своего рода "заготовки") и перехожу к след.-му.

      <StatusBarItem>
        <TextBlock Text="Статус:" />
      </StatusBarItem>
      <Separator Grid.Column="1" />
      <StatusBarItem Grid.Column="2">
        <TextBlock Text="Не отправлено" />
      </StatusBarItem>
      <Separator Grid.Column="3" />
      <StatusBarItem Grid.Column="4">
        <TextBlock Text="Кол-во знаков:" />
      </StatusBarItem>
      <Separator Grid.Column="5" />
      <StatusBarItem Grid.Column="6">
        <TextBlock Text="259" />
      </StatusBarItem>

Здесь появляется новый элемент StatusBarItem. Если прошлые элементы StatusBar.ItemsPanel и ItemsPanelTemplate служили нам заготовкой(разметкой), то уже этот служит нам для заполнения нужной информацией.

Каждый элемент размещается в своей колонке, привязка к определенной колонке происходит таким образом: Grid.Column="1" , где "1" это номер нашей колонки. Таким образом добавив нужные элементы(TextBlock и Separator) и привязав их к нужным колонкам у нас получится готовый StatusBar.

Продолжение следует.....

#WPF,#Csharp
В прошлом посте про WPF, рассмотрел элемент: StatusBar.
В текущем коснусь такого элемента, как TextBox и некоторых его свойств.

    <Grid>
      <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
      </Grid.RowDefinitions>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="5*"/>
        <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>
      <TextBox Grid.Column="0" AcceptsReturn="True" VerticalScrollBarVisibility="Auto"
     HorizontalScrollBarVisibility="Auto"/>
      <Button Grid.Column="1" x:Name="buttonSentMessage" Width="80" Height="30" Content="Отправить" Click="Button_Click" />
    </Grid>

Свойства:
AcceptsReturn="True" - служит для того, чтобы переводить по нажатию на клавишу Enter курсор на следующую строку.
VerticalScrollBarVisibility="Auto" и HorizontalScrollBarVisibility="Auto" - служит для отображения полос прокрутки TextBox поддерживает свойства.

Элемент: Button - где ему дал имя в свойстве: x:Name="buttonSentMessage"(это имя будет использоваться в коде).
Надпись(содержание), которая отображается на самой кнопке находится в свойстве: Content="Отправить".
Событие: Click="Button_Click" с собственным названием.

В коде будет примерно так(при нажатие на эту кнопку, выскакивает сообщение "Кнопка была нажата!"):

private void Button_Click(object sender, RoutedEventArgs e)
{
    MessageBox.Show("Кнопка была нажата!");
}

На этом шаге с оформлением останавливаюсь.

Продолжение следует.....

#WPF,#Csharp
4. В конф. проекта добавляем эту строку:
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
Она необходима для того, чтобы программа запускалась на всех операц. системах Windows.
Подробнее можно посмотреть по ссылке.

 #CSharp, #WPF