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

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

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

Как завершить консольное приложение .NET с заданным кодом

Print Friendly, PDF & Email

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

  1. объявить метод Main() с возвращаемым типом Integer;
  2. при завершении программы вызвать метод Environment.Exit(code).

Код завершения, естественно, желательно сделать перечислением для удобства, если интересуют подробности более чем успешно/неуспешно.

Print Friendly, PDF & Email

Как сделать пункт меню с выравниванием по правому краю (WPF)

Print Friendly, PDF & Email

Чтобы сделать в WPF в панели меню какие-то пункты с выравниваеним по правому краю (например, меню «Справка» или «О программе»), можно описать в XAML произвольную панель элементов, как в примере ниже:

<Menu>

    <Menu.ItemsPanel>
        <ItemsPanelTemplate>
            <DockPanel />
        </ItemsPanelTemplate>
    </Menu.ItemsPanel>

    <MenuItem Header="Item1" />
    <MenuItem Header="Item2" />
    <MenuItem Header="Справка" HorizontalAlignment="Right" />
</Menu>
Print Friendly, PDF & Email

WPF: выделение текста в TextBox при получении фокуса ввода

Print Friendly, PDF & Email

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

<TextBox PreviewMouseDown="IgnoreMouseButton" GotFocus="TextBox_GotFocus">

Вот реализация данных методов:

Private Sub TextBox_GotFocus(sender As Object, e As RoutedEventArgs)
    Dim tb As TextBox = TryCast(sender, TextBox)
        If (tb IsNot Nothing) Then
            tb.SelectAll()
        End If
    End Sub

Private Sub IgnoreMouseButton(sender As Object, e As MouseButtonEventArgs)
    Dim tb As TextBox = TryCast(sender, TextBox)
    If (tb IsNot Nothing) Then
        If (Not tb.IsKeyboardFocusWithin) Then
            e.Handled = True
            tb.Focus()
        End If
    End If
End Sub
Print Friendly, PDF & Email

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

Print Friendly, PDF & Email

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

Программный код для перевода чисел в разных системах счисления (разворачивается)
''' <summary>
''' Вспомогательные.
''' </summary>
<Runtime.CompilerServices.Extension()>
Public Module Helpers

    ''' <summary>
    ''' Преобразует число из десятичной системы счисления в число в восьмеричной системе счисления.
    ''' </summary>
    <Runtime.CompilerServices.Extension()>
    Public Function ToOctal(dec As Integer) As Integer
        Return ConvertFromTo(dec, 10, 8)
    End Function

    ''' <summary>
    ''' Преобразует число из десятичной системы счисления в число в двоичной системе счисления.
    ''' </summary>
    <Runtime.CompilerServices.Extension()>
    Public Function ToBinary(dec As Integer) As Integer
        Return ConvertFromTo(dec, 10, 2)
    End Function

    ''' <summary>
    ''' Преобразует число из заданной системы счисления в другую.
    ''' </summary>
    ''' <param name="number">Число в исходной системе счисления.</param>
    ''' <param name="fromBase">Исходная система счисления.</param>
    ''' <param name="toBase">Целевая система счисления.</param>
    ''' <remarks>
    ''' Будьте внимательны: при переводе в двоичную систему может возникнуть ошибка переполнения, т.к. двоичные числа могут быть очень длинные.
    ''' Также здесь не реализован перевод чисел из и в 16-ную систему счисления, в которой применяется цифро-буквенная нотация.
    </remarks>
    Public Function ConvertFromTo(number As Integer, fromBase As Integer, toBase As Integer) As Integer
        Dim result As Integer = 0
        Dim i As Integer = 0
        Do While (number <> 0)
            result += (number Mod toBase) * CInt(Math.Pow(fromBase, i))
            number = CInt(Math.Truncate(number / toBase))
            i += 1
        Loop
        Return result
    End Function

End Module
Print Friendly, PDF & Email

Как создать безрамочное окно в WPF

Print Friendly, PDF & Email

Чтобы создать окно без рамок и без стандартных элементов управления, в файле разметки в свойствах окна достаточно добавить 3 атрибута: WindowStyle, AllowsTransparency и Background.

<Window x:Class="BorderlessWindow"
        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"
        mc:Ignorable="d"
        WindowStyle="None"
        AllowsTransparency="True"
        Background="Transparent"
        MouseLeftButtonDown="Window_MouseLeftButtonDown"
        Title="Hello, Soltau.ru"
        Width="200" Height="200">
    <Grid>
        <Rectangle Fill="Yellow" Opacity="0.7" RadiusX="40" RadiusY="40" />
        <Button Width="100" Height="30" Content="Закрыть" Click="Button_Click" />
    </Grid>
</Window>

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

Public Class BorderlessWindow

    Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
        Me.Close()
    End Sub

    Private Sub Window_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs)
        Me.DragMove()
    End Sub

End Class

Выглядеть это будет примерно так:

Окно без рамок в WPF
Окно без рамок в WPF
Print Friendly, PDF & Email

Красивое диалоговое окно в .NET

Print Friendly, PDF & Email

Чтобы вместо стандартного MessageBox в приложении WPF использовать более современное и «красивое» окно, можно использовать средства самой Windows. Напишем класс-помощник, который будет выводить диалоговое окно, используя системную библиотеку comctl32.dll.

Imports System.Runtime.InteropServices

''' <summary>
''' "Красивое" диалоговое окно.
''' </summary>
Public Module TaskDialogHelper

    <DllImport("comctl32.dll", CharSet:=CharSet.Unicode, PreserveSig:=False)>
    Public Function TaskDialog(hwndParent As IntPtr, hInstance As IntPtr, title As String, mainInstruction As String, content As String, buttons As TaskDialogButtons, icon As TaskDialogIcon) As TaskDialogResult
    End Function

    Public Enum TaskDialogResult As Integer
        Ok = 1
        Cancel = 2
        Retry = 4
        Yes = 6
        No = 7
        Close = 8
    End Enum

    <Flags>
    Public Enum TaskDialogButtons As Integer
        Ok = &H1
        Yes = &H2
        No = &H4
        Cancel = &H8
        Retry = &H10
        Close = &H20
    End Enum

    Public Enum TaskDialogIcon As Integer
        Shield = 65532
        Information 
        [Error] 
        Warning 
    End Enum

End Module

Также в манифесте проекта необходимо раскомментировать следующий участок:

  <dependency>
    <dependentAssembly>
      <assemblyIdentity
          type="win32"
          name="Microsoft.Windows.Common-Controls"
          version="6.0.0.0"
          processorArchitecture="*"
          publicKeyToken="6595b64144ccf1df"
          language="*"
        />
    </dependentAssembly>
  </dependency>

Использовать код можно таким образом:

Dim dr = TaskDialogHelper.TaskDialog(New System.Windows.Interop.WindowInteropHelper(Me).Handle,
    IntPtr.Zero,
    "Лаконичный заголовок окна",
    "Здесь будет основной текст сообщения.",
    "А здесь вспомогательный.",
    TaskDialogHelper.TaskDialogButtons.Yes Or TaskDialogHelper.TaskDialogButtons.No,
    TaskDialogHelper.TaskDialogIcon.Information)

Желательно также при выводе данного окна проверять версию операционной системы: данное окно можно использовать в Windows Vista и более современных (версия больше 6):

If (System.Environment.OSVersion.Version.Major >= 6) Then 
    …
Print Friendly, PDF & Email

Изменяемая асинхронно наблюдаемая коллекция ObservableCollection

Print Friendly, PDF & Email

Наблюдаемые коллекции ObservableCollection в WPF можно изменять толкько в потоке пользовательского интерфейса. Однако можно несколько изменить данную коллекцию таким образом, чтобы можно было это делать из фонового потока. Например, вот так:

Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Collections.Specialized
Imports System.Diagnostics
Imports System.Windows.Threading

Public Class ObservableCollectionThreadSafe(Of T)
    Inherits ObservableCollection(Of T) 'наследуем от наблюдаемой коллекции

    'Переопределяем событие изменения коллекции
    Public Shadows Event CollectionChanged As NotifyCollectionChangedEventHandler

#Region "КОНСТРУКТОРЫ"

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

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

#End Region '/КОНСТРУКТОРЫ

    Protected Overrides Sub OnCollectionChanged(e As NotifyCollectionChangedEventArgs)
        Using MyBase.BlockReentrancy() 'используем BlockReentrancy(), который запрещает выполнение повторных попыток изменения коллекции
            Dim eventHandler As NotifyCollectionChangedEventHandler = Me.CollectionChangedEvent
            If (eventHandler IsNot Nothing) Then
                Dim delegates As [Delegate]() = eventHandler.GetInvocationList()
                For Each handler As NotifyCollectionChangedEventHandler In delegates 'идём по списку вызовов 
                    Dim dispatcherObject As DispatcherObject = TryCast(handler.Target, DispatcherObject)
                    If (dispatcherObject IsNot Nothing) AndAlso (Not dispatcherObject.CheckAccess()) Then 'Если подписчик - DispatcherObject И другой поток
                        dispatcherObject.Dispatcher.Invoke(DispatcherPriority.DataBind, handler, Me, New Object() {e}) 'вызываем обработчик в целевом потоке диспетчера
                    Else
                        handler(Me, e) 'иначе запускаем обработчик как есть
                    End If
                Next
            End If
        End Using
    End Sub

End Class
Print Friendly, PDF & Email

Как выключить вход с паролем в операционной системе Windows

Print Friendly, PDF & Email
Чтобы в Windows отключить вход по паролю, нужно:
  1. запустить редактор реестра; это можно сделать, например, набрав в командной строке regedit4;
  2. найти ветку реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon;
  3. задать параметр AutoAdminLogon равным 1;
  4. указать пароль по умолчанию для параметра DefaultPassword.
Print Friendly, PDF & Email

Запрет выделения элементов ListBox / ListView (WPF)

Print Friendly, PDF & Email

Чтобы запретить выделение элементов элемента ListBox или ListView, можно определить это с помощью такого стиля:

<ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
         <Setter Property="Focusable" Value="False" />
    </Style>
</ListBox.ItemContainerStyle>

Второй вариант – использовать вместо ListBox элемент ItemsControl.

Print Friendly, PDF & Email

Объединение словарей и стилей в секции ресурсов в 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
Subscribe to this RSS feed