Рейтинг@Mail.ru
Полезные советы

Полезные советы (40)

Короткие практические полезные советы из области ИТ.

WPF: Как сохранить элемент управления FrameworkElement() в виде изображения

Допустим, нам нужно сохранить какой-то элемент управления в окне WPF в изображение. Можно сделать это, например, так.

Сначала сгенерируем изображение с помощью класса RenderTargetBitmap(), запишем его в поток в памяти, прочитаем и сохраним в объект типа String():

''' <summary>
''' Генерирует строку, представляющую поток изображения, из FrameworkElement.
''' </summary>
''' <param name="elem">Элемент, который будет преобразован в изображение.</param>
Private Function GetElementAsString(ByVal elem As FrameworkElement) As String    
    Dim w As Integer = CInt(elem.ActualWidth)
    Dim h As Integer = CInt(elem.ActualHeight)
    Dim renderBitmap As New RenderTargetBitmap(w, h, 96, 96, PixelFormats.Default)
    renderBitmap.Render(elem)

    Dim pngEncoder As New PngBitmapEncoder()
    pngEncoder.Frames.Add(BitmapFrame.Create(renderBitmap))

    Dim pngStr As String = String.Empty
    Using ms As New IO.MemoryStream()
        pngEncoder.Save(ms)
        ms.Seek(0, IO.SeekOrigin.Begin)
        Using sr As New IO.StreamReader(ms, Text.Encoding.Default)
            pngStr = sr.ReadToEnd
        End Using
    End Using
    Return pngStr
End Function

Напишем метод для сохранения изображения в файл:

''' <summary>
''' Сохраняет строку с данными изображения в файл PNG с заданным именем.
''' </summary>
''' <param name="fileName">Имя файла с расширением PNG, под которым будет сохранено изображение.</param>
''' <param name="imgStr">Строка, представляющая изображение.</param>
Private Sub SaveElementAsImage(ByVal fileName As String, ByVal imgStr As String)
    Using fs As New IO.FileStream(fileName, IO.FileMode.Create)
        Using sw As New IO.StreamWriter(fs, Text.Encoding.Default)
            sw.Write(imgStr)
        End Using
    End Using
End Sub

Теперь мы можем сохранить изображение в файл, используя предыдущие два метода:

Dim pngStr As String = GetElementAsString(MyControlToSave)
SaveElementAsImage("1.png", "Рисунок 1")

LINQ+VB.NET: Выбор объектов DateTime() с уникальными значениями минут

Допустим, у нас есть упорядоченный список объектов MyList() типа даты: List(of DateTime), и нам нужно выбрать из него только те объекты, которые имеют уникальные значения минут (или часов, или секунд, и т.п.). Выберем только первые встреченные значения с уникальным параметром. Для этого можно воспользоваться языком запросов LINQ и языком VB.NET.

Вариант 1 (самый быстрый)

Dim selected As IEnumerable(Of DateTime) = MyList.GroupBy(Function(d As DateTime) d.TimeStamp.Minute).[Select](Function(g) g.First)

Вариант 2

Dim selected As IEnumerable(Of IGrouping(Of Integer, DateTime)) = MyList.GroupBy(Function(n As DateTime) (n.Minute)).Distinct

Вариант 3 (самый медленный, использует преобразование к типу Lookup())

Dim selected As ILookup(Of Integer, DateTime) = MyList.ToLookup(Of Integer, DateTime)(Function(ByVal x As DateTime) x.Minute, Function(ByVal y As DateTime) y)

WPF: Использование системных цветов

Для использования системных цветов в XAML необходимо объявить цвет в секции ресурсов:

<Window.Resources>
    <SolidColorBrush x:Key="sysColor" Color="{DynamicResource {x:Static SystemColors.ControlColorKey}}" />
</Window.Resources>

А затем его можно использовать в разметке так:

<Menu Background="{StaticResource sysColor}"></Menu>

Как проверить версию .NET, установленную на компьютере

Для того чтобы определить, что в системе установлена платформа .NET, можно проверить в системном каталоге C:\Windows\System32\ наличие файла mscoree.dll – основного файла платформы .NET.

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

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP

В этом разделе будут находиться подразделы установленных версий .NET, например: v3.0, v3.5, v4.0 и т.д.

WPF: Изменение источника элементов при изменении свойства

Чтобы динамически изменять коллекцию – источник привязки, можно воспользоваться триггерами данных DataTrigger:

<Style TargetType="ComboBox" x:Key="comboSourceStyle">
  <Style.Triggers>
    <DataTrigger Binding="{Binding Speed}" Value="0">
      <Setter Property="ItemsSource" Value="{StaticResource MyCollection1}" />
    </DataTrigger>
    <DataTrigger Binding="{Binding Speed}" Value="1">
      <Setter Property="ItemsSource" Value="{StaticResource MyCollection2}" />
    </DataTrigger>
  </Style.Triggers>
</Style>

Создание архива 7zip с помощью bat-файла

Для того чтобы быстро создавать архив с помощью архиватора 7zip, напишем такой скрипт и сохраним его с расширением ".bat":

start cmd /c ""c:\Program Files\7-Zip\7z.exe"" a d:\Baсkup\%DATE:~0,2%.%DATE:~3,2%.%DATE:~-4%.7z d:\Projects

Этот скрипт автоматически называет файл в соответствии с текущей датой. Чтобы скрипт запускался автоматически, можно создать в планировщике задач Windows задание и указать расписание: Панель управления – Администрирование – Планировщик заданий. В планировщике нажимаем Создать задачу, на вкладке Действие добавляем Запуск программы и указываем путь к нашему bat-файлу. Настраиваем расписание на вкладке Триггеры.

Что делать если изображение видно в редакторе XAML, но при выполнении приложения - нет

У вас ситуация: в редакторе XAML в Visual Studio вы задали визуальный элемент Image, который использует картинку из папки проекта. Вы видите её в редакторе, всё нормально. Но стоит запустить скомпилированное приложение – и изображения в нём не видно. Что делать?

Иногда помогает очистка решения и перекомпиляция: Построение Очистить, Построение Перестроить проект.

Если не помогло, кликаем правой кнопкой мыши на изображении в обозревателе решений, выбираем Свойства, в открывшейся панели свойств идём в Действия при сборке (BuildActions) "Нет" меняем на Ресурс (Resource).

Панель свойств изображения в Visual Studio 2013

XAML: Почему текст в ListView не переносится на новую строку

По умолчанию, если ширина элемента списка ListView больше, чем ширина списка, его содержимое не переносится на новую строку. Чтобы перенос происходил, нужно использовать шаблон DataTemplate, применённый к элементу списка:

<ListView ItemsSource="{Binding myCollection}" ItemTemplate="{StaticResource lvDataTemplate}" />

Шаблон будет таким:

<DataTemplate x:Key="lvDataTemplate">
    <TextBlock Text="{Binding}" TextWrapping="Wrap" />
</DataTemplate>

WPF: Как подогнать ширину столбцов GridView под содержимое элементов

Чтобы подогнать ширину всех столбцов таблицы GridView под ширину содержимого можно воспользоваться таким решением:

For Each gvc As GridViewColumn In myListView.View.Columns
    If Double.IsNaN(gvc.Width) Then
        gvc.Width = gvc.ActualWidth
        gvc.Width = Double.NaN
    End If
Next

Как быстро запустить произвольную программу из командной строки Windows

Чтобы запустить графический редактор Paint достаточно нажать Win + R, ввести в поле mspaint и нажать кнопку Enter. А как запустить программу, не входящую в стандартный набор программ, так же быстро и просто? Давайте для примера будем запускать графический редактор Paint.NET аналогичным образом.

  1. Откроем Свойства системы Дополнительно Переменные среды.
  2. Находим переменную PATH, нажимаем на неё и на кнопку Изменить.
  3. Если у вас Windows XP или Windows 7, через точку с запятой добавляем путь к исполняемому файлу программы, например: c:\Program Files\Java\jdk1.8.0_05\bin\;c:\Program Files\Paint.NET\ и перезагрузим компьютер, чтобы операционная система прочитала данные о новой переменной среды. Если у вас Windows 10, то нажимаем кнопку Добавить и вводим то же самое; перезагружать не обязательно.
  4. Чтобы не вводить длинное имя запускаемого файла, в директории, которую мы указали, создадим с помощью блокнота файл pdn.bat с таким содержимым:
  5. start PaintDotNet.exe
  6. Теперь для запуска Paint.NET из командной строки достаточно набрать Win+R pdn Enter.
Добавление новой переменной среды для произвольной программы в Windows
Добавление новой переменной среды для произвольной программы в Windows

WPF: Как привязать ComboBox к целочисленному массиву в XAML

Сначала в разделе ресурсов создадим целочисленный массив, не забыв импортировать пространство имён mscorlib:

<Window xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <Window.Resources>

        <x:Array Type="{x:Type sys:Int32}" x:Key="refreshPeriods">
            <sys:Int32>100</sys:Int32>            
            <sys:Int32>500</sys:Int32>
            <sys:Int32>1000</sys:Int32>
            <sys:Int32>2000</sys:Int32>
        </x:Array>

И теперь используем ComboBox так:

<ComboBox ItemsSource="{StaticResource refreshPeriods}" SelectedValue="{Binding UpdateDiagramTimerPeriod, Mode=TwoWay}" />

WPF: Как обновить GUI при быстро изменяющихся событиях

Добавить обработчик по таймеру:

Private updateGuiTimer As DispatcherTimer

'При загрузке окна инициализируем и запускаем таймер.
Private Sub winLoaded(sender As Object, e As RoutedEventArgs)
    updateGuiTimer = New DispatcherTimer()
    updateGuiTimer.Interval = TimeSpan.FromMilliseconds(100) 'задаём период обновления
    AddHandler updateGuiTimer.Tick, AddressOf updateGui
    updateGuiTimer.Start()
End Sub

'Обработчик события Timer.Tick().
Private Sub updateGui(ByVal sender As Object, ByVal e As EventArgs)
    txtLabel.Text = LabelPropValue 'здесь обновлять элементы GUI
End Sub

Добавить обработчик события ререндеринга (происходит около 60 раз в секунду).

Private Sub winLoaded(sender As Object, e As RoutedEventArgs)
    AddHandler CompositionTarget.Rendering, AddressOf OnRendering
End Sub

Public Sub OnRendering(sender As Object, e As EventArgs)
    txtLabel.Text = SomeProp.ToString() 'здесь обновлять необходимые элементы GUI
End Sub

Как отключить учётную запись в Windows 10

Чтобы отключить учётную запись пользователя в Windows 10 без её удаления, необходимо запустить консоль от имени Администратора. Для отключения введите в консоль:

net user USERNAME /active:yes

и нажмите Ввод (Enter). Здесь USERNAME – имя пользователя, учётную запись которого необходимо отключить.

Для отключения учётной записи:

net user USERNAME /active:no
Подписаться на этот канал RSS