Показаны сообщения с ярлыком WPF. Показать все сообщения
Показаны сообщения с ярлыком WPF. Показать все сообщения

12.09.2018

WPF: несколько полезных трюков

Недавно закончил работу над десктопным WPF-приложением. В нем я столкнулся с рядом задач, решение которых было не совсем очевидно, и я хочу ими поделиться.

1. Биндинг команд к событиям
Если разработчик хочет придерживаться MVVM модели, то для обработки событий он не сможет использовать стандартный обработчик команды в codebehind его xaml-формы. Для того, чтобы привязать событие и команду из ViewModel, он может использовать трюк, который предлагает JonghoL. В этом случае вам нужно просто написать следующий код:


Здесь добавляется пространство имен eb, в котором реализован класс EventBinding, который, в свою очередь может получать на вход название команды из ViewModel и возвращать в неё параметр.


2. Конвертер строки в BitmapImage
Когда программист добавляет на форму изображение и делает связку источника изображения с путем к какому-либо файлу, то доступ к данному файлу блокируется. Это не всегда удобно, например, если вы разрабатываете редактор изображений, то вам может понадобиться сохранение и удаление временных файлов, а они будут залочены элементом управления. В такой ситуации можно написать конвертер, преобразующий путь к изображению в BitmapImage, и использовать его при биндинге как обычный конвертер. Конвертер будет выглядеть так:

public sealed class StringToBitmapImageConverter : ValueConverterBase
{
    public override object Convert(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        object result = null;

        if (value is string uri)
        {
            BitmapImage image = new BitmapImage();
            image.BeginInit();
            image.CacheOption = BitmapCacheOption.OnLoad;
            image.UriSource = new Uri(uri);
            image.EndInit();
            result = image;
        }

        return result;
    }
    
    public override object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}


3. Создание пунктирной рамки 
В WPF нет стандартной кисти для реализации пунктирной линии границы. Для реализации такого стиля существуют разные подходы, в т.ч. с использованием codebehind. Приведу тот, который нравится мне, при необходимости его можно модифицировать под конкретную задачу:
<LinearGradientBrush x:Key="CropRectangleAreaBorderBrush" 
                     MappingMode="Absolute"
                     SpreadMethod="Repeat"
                     StartPoint="0,0"
                     EndPoint="30,30">
    <GradientStop Offset="0" Color="#40009299" />
    <GradientStop Offset="0.5" Color="#40169E4C" />
    <GradientStop Offset="0.501" Color="Transparent" />
</LinearGradientBrush>


PS. Функциональность, представленная в пунктах 1 и 2, а также множество других полезных классов и методов, доступна в разрабатываемом мной фреймворке на github, а такжк в nuget-пакетах: Ak.Framework.Wpf и Ak.Framework.Core.

30.08.2018

WPF: Binding

Последнее время приходится много писать на WPF. Открыл для себя неплохую шпаргалку по синтаксису биндинга. Может быть полезна для тех, кто только начинает работу с WPF. Файл  доступен по ссылке.

03.01.2017

WPF: Error- "Default value type does not match type of property..."

At last I have my holidays and some spare time to write more posts to my blog. :)

When trying to add dependency property of type double you can easily get the error "Default value type does not match type of property..." with such code:
public double SomeDoubleValue
{
    get { return (double)GetValue(SomeDoubleValueProperty); }
    set { SetValue(SomeDoubleValueProperty, value); }
}
 
public static readonly DependencyProperty SomeDoubleValueProperty=
    DependencyProperty.Register("SomeDoubleValue", typeof(double),
    typeof(ownerclass), new PropertyMetadata(0));

The problem here is that "0" is not casted as double, that is why you should cast it explicitly like
public static readonly DependencyProperty SomeDoubleValueProperty=
    DependencyProperty.Register("SomeDoubleValue", typeof(double), 
    typeof(ownerclass), new PropertyMetadata(0D));

Some more information can be found here.