WPF tricks

13.07.2015 at 07:58

Переопределение стиля по типу контрола

Иногда возникает ситуация, когда нужно переопределить стиль, который навешивается не по ключу, а по типу. Делается это очень просто: в роли ключа у такого типа выступает TargetType:

< Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}" x:Key="InputTextBox">

Обновление биндинга руками

Осторожно, костыль! Если вам нужно обновлять биндинги руками, значит что-то уже пошло не так и у вас нарушен MVVM.

Биндинг руками обновляется очень просто. Обновление таргета:

BindingOperations.GetBindingExpression(control, ControlType.Property).UpdateTarget();

Обновление соурса:

BindingOperations.GetBindingExpression(control, ControlType.Property).UpdateSource();

Для биндингов на коллекции это не сработает, нужно делать по-другому:

CollectionViewSource.GetDefaultView(listControl.ItemsSource).Refresh();

Копирование картинки контрола

private static System.Drawing.Image CropImage(System.Drawing.Image img, Rectangle cropArea)
{
	Bitmap bmpImage = new Bitmap(img);
	return bmpImage.Clone(cropArea, bmpImage.PixelFormat);
}

internal static System.Drawing.Image GetControlSream(FrameworkElement control)
{
	RenderTargetBitmap rtb = new RenderTargetBitmap((int)control.ActualWidth, (int)control.ActualHeight, 96, 96, PixelFormats.Pbgra32);
	rtb.Render(control);
	PngBitmapEncoder png = new PngBitmapEncoder();
	png.Frames.Add(BitmapFrame.Create(rtb));
	MemoryStream stream = new MemoryStream();
	png.Save(stream);
	var image = System.Drawing.Image.FromStream(stream);
	return CropImage(image, new Rectangle(1, 1, (int)control.ActualWidth - 2, (int)control.ActualHeight - 2));
}

CropImage здесь нужен для того, чтобы убрать рамку вокруг контрола (рамка является частью контрола, а контрол — сторонний). Если такой проблемы нет — можно сразу возвращать image.

Я использовал это для того, чтобы вставлять графики из OxyPlot в отчет в PDF.

Tags: