WPF tricks
Переопределение стиля по типу контрола
Иногда возникает ситуация, когда нужно переопределить стиль, который навешивается не по ключу, а по типу. Делается это очень просто: в роли ключа у такого типа выступает 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.