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

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

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

Объединение словарей и стилей в секции ресурсов в XAML

Print Friendly, PDF & Email

Чтобы в секции ресурсов документа XAML использовать и словари, и стили, можно сделать следующее:

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>

        <!-- Словарь стилей -->
        <ResourceDictionary Source="Dictionaries\WidgetTmiDictionary.xaml" />
    
        <!-- Определение дополнительных стилей -->
        <ResourceDictionary>
	        <Image Source="Images\1.png" x:Key="ic1" />
	        <Image Source="Images\2.png" x:Key="ic2" />                  
        </ResourceDictionary>

        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>
Print Friendly, PDF & Email

Как определить текущую привязку Binding элемента UI

Print Friendly, PDF & Email

Допустим, что мы задали в XAML для текстового элемента TextBlock привязку и хотим узнать её в застраничном коде. Это делается так:

    Dim be As BindingExpression = myTextBlock.GetBindingExpression(TextBlock.TextProperty)
    Dim bnd As Binding = be.ParentBinding
    Dim bindingPath As String = bnd.Path.Path
Print Friendly, PDF & Email

Измерение времени выполнения кода в .NET

Print Friendly, PDF & Email

Для измерения времени выполнения кода лучше не использовать метод DateTime.Now(). Лучше воспользоваться классом StopWatch. Это даст более адекватное значение, т.к. этот класс требует меньше накладных расходов на свою работу.

    Dim sw As New System.Diagnostics.Stopwatch()
    sw.Start()
    … выполнение кода, который мы хотим измерить …
    sw.Stop()
    Console.Write(sw.Elapsed)
Print Friendly, PDF & Email

Аналог StartupPath в WPF

Print Friendly, PDF & Email

В приложениях Windows Forms была возможность определить каталог, из которого запускалось приложение, так:

    Dim startup As String = Application.StartupPath

В WPF данная возможность не работает. Теперь для определения текущей директории приложения нужно вызвать следующий код:

    Dim startup As String = System.AppDomain.CurrentDomain.BaseDirectory
Print Friendly, PDF & Email

Observable collection с уведомлением при добавлении диапазона значений

Print Friendly, PDF & Email

В .NET есть такой перечислимый тип как ObservableCollection. Его особенность в том, что эта коллекция при изменении её элементов (добавлении или удалении), уведомляет наблюдающие за ней классы об этом изменении. Это бывает полезно, например, когда к данной коллекции привязаны элементы пользовательского интерфейса. Но если необходимо добавить в коллекцию сразу множество элементов, то добавление каждого элемента будет уведомлять об изменении коллекции каждый раз. Это вызовет избыточную нагрузку на пользовательский интерфейс, и он может даже зависнуть на какое-то время. Чтобы этого избежать, можно написать свой собственный класс, который будет наследовать от ObservableCollection и содержать метод добавления множества элементов за один раз, а уведомлять об этом единожды. Вот как например это можно сделать:

Imports System.Collections.Specialized

''' <summary>
''' ObservableCollection с поддержой добавления множества элементов.
''' </summary>
Public Class ObservableRangeCollection(Of T)
    Inherits ObjectModel.ObservableCollection(Of T)

#Region "CTORs"

    Public Sub New()
        MyBase.New()
    End Sub

    Public Sub New(collection As IEnumerable(Of T))
        MyBase.New(collection)
    End Sub

#End Region '/CTORs

#Region "METHODS"

    ''' <summary>
    ''' Добавляет в коллекцию несколько элементов и в конце уведомляет об этом.
    ''' </summary>
    Public Sub AddRange(collection As IEnumerable(Of T))
        For Each item As T In collection
            Items.Add(item)
        Next
        OnCollectionChanged(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, collection))
    End Sub

#End Region '/METHODS

End Class

По аналогии с методом AddRange можно добавить методы для удаления, вставки или перемещения набора элементов коллекции.

Print Friendly, PDF & Email

Нюансы запуска процесса в .NET

Print Friendly, PDF & Email

Как известно, среда .NET позволяет запускать процесс с параметрами. Есть несколько интересных особенностей, о которых хочется упомянуть. Например, чтобы получать уведомление о завершении вызванного процесса, следует явно его включить:

Dim proc As New Process With {
    .EnableRaisingEvents = True 
}

А теперь можно назначить обработчик события завершения процесса:

AddHandler proc.Exited, Sub()
                            Console.WriteLine("The process has exited!")
                        End Sub

Также можно запустить процесс, не используя стандартную консоль CMD.exe, а перенаправив вывод в запускающее приложение:

Dim psi As New ProcessStartInfo() With {
                .UseShellExecute = False,
                .RedirectStandardOutput = True,
                .RedirectStandardInput = True
}
Dim proc As New Process With { .StartInfo = psi }
Print Friendly, PDF & Email

Форматирование текста с привязкой в XAML

Print Friendly, PDF & Email

Язык разметки XAML поддерживает форматирование, как и сама платформа .NET. Например, этот код фоматирует числовое значение как число с плавающей точкой с 3 знаками после запятой

<TextBlock Text="{Binding NumericValue, StringFormat=F3}" />

Вот так можно отформатировать простой текст:

<TextBlock Text="{Binding Title, StringFormat={}Название: {0}}"/>

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

<TextBlock>
    <TextBlock.Text>
        <MultiBinding StringFormat="{} Его зовут {0} {1}">
            <Binding Path="Name" />
            <Binding Path="Surname" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

А этот код форматирует дату и время с точностью до миллисекунд:

<TextBlock Text="{Binding Value, StringFormat={}{YYYY-MM-dd, HH-mm-ss.FFF}}" />

А вот так можно отформатировать в текущей культуре приложения цену с указанием валюты:

<TextBlock Text="{Binding Path=Price, StringFormat=c}"/>
Print Friendly, PDF & Email

Как изменить языковые настройки на уровне приложения WPF

Print Friendly, PDF & Email

Допустим, вы пишете приложение WPF. И при обработке строк часто бывает задача преобразования строки в число с плавающей запятой. В русском языке разделитель целой и дробной части – запятая, а в других языках (например, английском) – точка. И вы не хотите каждый раз задавать настройки культуры в этом и других случаях, которые требуют определения текущей культуры. В таком случае можно в файле Application.xaml определить функцию, которая выполняется при загрузке приложения:

<Application x:Class="Application"
    Startup="Application_Startup"
    ...>

Далее в застраничном коде Application.xaml.vb или Application.xaml.cs задаём для текущего потока новые языковые настройки таким способом:

Class Application

    Private Sub Application_Startup(sender As Object, e As StartupEventArgs)
        Thread.CurrentThread.CurrentCulture = New Globalization.CultureInfo("en-US")
    End Sub
	
End Class    

Теперь для всего приложения действует культура en-US, и все строки типа "3,14" и других будут корректно преобразовываться в числа. Это же проявится и во всех остальных случаях: форматирование даты и времени, валюты и прочих, где проявляются культурные особенности того или иного языка.

Print Friendly, PDF & Email

Множественная привязка в WPF

Print Friendly, PDF & Email

Как сделать привязку (binding) визуального элемента в WPF к нескольким свойствам? Для этого существует так назваемая множественная привязка. Вот пример разметки, который использует свойства FirstName и LastName некоторого объекта для вывода их посредством одного элемента TextBlock:

<TextBlock>
  <TextBlock.Text>
    <MultiBinding StringFormat="{}{0} {1}">
      <Binding Path="FirstName" />
      <Binding Path="LastName" />
    </MultiBinding>
  </TextBlock.Text>
</TextBlock>

Формат вывода текста определяется атрибутом StringFormat. Обратите внимание на пустые фигурные скобки в начале определения формата строки. Они подсказывают парсеру XAML, что здесь используется привязка.

Добиться подобного же результата можно также с помощью конвертера MultiValueConverter, который принимает несколько значений. Вот тот же пример, но с использованием конвертера. Сначала необходимо написать класс самого конвертера:

Public Class PersonNameMultiConverter
    Implements IMultiValueConverter

        Public Function Convert(values() As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IMultiValueConverter.Convert
            If (values.Length > 0) Then
                Dim firstName As String = values(0).ToString()
                Dim lastName As String = values(1).ToString()
                Return firstName & " " & lastName
            End If
            Return String.Empty
        End Function

        Public Function ConvertBack(value As Object, targetTypes() As Type, parameter As Object, culture As CultureInfo) As Object() Implements IMultiValueConverter.ConvertBack
            Throw New NotImplementedException()
        End Function
End Class

Далее в начале XAML файла, в котором планируется использовать данный конвертер, в разделе ресурсов необходимо объявить соответствующий ресурс:

<conv:PersonNameMultiConverter x:Key="personNameMultiConverter" />

И далее создадим текстовое поле и добавим ему привязку:

<TextBlock>
  <TextBlock.Text>
    <MultiBinding Converter="{StaticResource personNameMultiConverter}">
      <Binding Path="FirstName" />
      <Binding Path="LastName" />
    </MultiBinding>
  </TextBlock.Text>
</TextBlock>

Гораздо больше кода потребовалось, чем в первом варианте, верно? Однако преимуществом последнего метода является то, что конвертеру можно передавать сложные объекты и производить с ними какую-либо серьёзную обработку, что попросту невозможно при использовании первого варианта.

Print Friendly, PDF & Email

Как в XAML сделать привязку к значению системной переменной

Print Friendly, PDF & Email

Допустим, мы хотим прямо в XAML сделать привязку непосредственно к системной переменной. Скажем, вывести в элементе TextBlock максимальное значение для типа System.UInt64 (беззнаковое 64-разрядное целое). Для этого необходимо:

  1. В начале страницы/окна добавить ссылку на пространство имён System:
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
  2. В XAML коде страницы ссылка на тип будет иметь следующий вид:
    <TextBlock Text="{x:Static Member=sys:UInt64.MaxValue}" />
    или проще:
    <TextBlock Text="{x:Static sys:UInt64.MaxValue}" />
Print Friendly, PDF & Email

Если не работает мышь в МСВС, запущенной на виртуальной машине

Print Friendly, PDF & Email
Если у вас установлена операционная система МСВС на виртуальной машине (VMWare, VirtualBox и других) и не работает мышь, следует попробовать вот что.
  • Зайти в панель управления, в раздел «Оборудование».
  • Выбрать настройки параметров мыши.
  • Выставить следующие настройки: интерфейс PS/2 (мышь может быть и USB), модель MS IntelliMouse, устройство /dev/psaux, и поставить галку «Мышь с колёсиком».
  • Перезагрузить ОС МСВС на виртуальной машине.

После этого мышь должна заработать.

Настройки мыши в ОС МСВС
Настройки мыши в ОС МСВС
Print Friendly, PDF & Email

Что делать, если Quartus не видит USB Blaster

Print Friendly, PDF & Email

Если вы корректно установили драйверы для программатора USB Blaster, а он всё равно не видится из среды Quartus II и выдаёт что-то такое:

Сообщение об ошибке при загрузке Quartus ii 8.1
Skipped: unable to execute ./bin64/jtagserver.exe --uninstall
Skipped: unable to execute ./drivers/sentinel/win_xp64/sentinst71xp64.exe /S /v"/qn"
mount: warning: couldn't determine mount type.
Success: .\bin\cygwin\cygreg.bat c:\altera\81\quartus\bin\cygwin
Error: './bin/perl/bin/perl.exe ./sopc_builder/bin/regsopc.pl --quartus_root_dir=c:/altera/81/quartus' failed with code: -1073741515
Skipped: unable to execute ./bin64/jtagserver.exe --install
 
Skipped: './bin64/jtagserver.exe --uninstall' failed with code: 4
Success: ./drivers/sentinel/win_xp64/sentinst71xp64.exe /S /v"/qn"
Success: .\bin\cygwin\cygreg.bat c:\altera\81\quartus\bin\cygwin
Error: './bin/perl/bin/perl.exe ./sopc_builder/bin/regsopc.pl --quartus_root_dir=c:/altera/81/quartus' failed with code: -1073741515
Success: ./bin64/jtagserver.exe --install


Или Quartus выдаёт ошибку с кодом 82:

Сообщение об ошибке "82" сервера JTAG при загрузке Quartus ii 13.1
Сообщение об ошибке "82" сервера JTAG при загрузке Quartus ii 13.1

Вероятнее всего, что проблема в сервере JTAG. Бывает, что его блокирует антивирус или фаервол. В таком случае, если файл jtagserver.exe не находится в директории quartus\bin и quartus\bin64, то следует его восстановить из вирусного хранилища и добавить в список исключений. Если же файл присутствует в указанных директориях, то следует отключить антивирус и фаервол, в затем запустить файл с параметром:
jtagserver.exe --install.

После этого USB Blaster должен появиться в списке оборудования (Hardware).

Print Friendly, PDF & Email

Параметры проекта по умолчанию в Visual Studio

Print Friendly, PDF & Email

Рекомендую при написании кода в Visual Studio на VB.NET всегда использовать жёсткую проверку соответствия типов, которая задаётся директивой Option Strict. При создании нового проекта с настройками среды по умолчанию, используется нестрогая проверка. Чтобы каждый раз не менять данную директиву в свойствах проекта, её можно поменять в настройках Visual Studio: Options — Projects and Solutions — VB Defaults — Option Strict

Настройки по умолчанию для новых проектов, создаваемых в Visual Studio
Настройки по умолчанию для новых проектов, создаваемых в Visual Studio
Print Friendly, PDF & Email
Subscribe to this RSS feed