При изучение системы компоновки WPF у меня возникла куча вопросов, мне казалось что я разобрался с ними, до того момента пока не попытался сам сделать пару классов,поэкспериментировать. Вот тут я и понял, что абсолютно ничего не понимаю.
Вот маленький простой класс, я даже не могу понять почему он не работает:
class Block : FrameworkElement
{
Rectangle block;
public Brush Fill
{
get => block.Fill;
set => block.Fill = value;
}
public Block()
{
block = new Rectangle();
AddVisualChild(block);
AddLogicalChild(block);
}
protected override Size MeasureOverride(Size availableSize)
{
block.Measure(new Size(Width,Height));
return block.DesiredSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
block.Arrange(new Rect(new Point(0,0),finalSize));
return finalSize;
}
}
class A : Window
{
[STAThread]
static void Main()
{
new Application().Run(new A());
}
public A()
{
Block b = new Block();
b.Fill = Brushes.Black;
b.Height = b.Width = 10;
b.HorizontalAlignment = HorizontalAlignment.Center;
b.VerticalAlignment = VerticalAlignment.Center;
Content = b;
}
}
DesiredSize = (0;0)
Зачем нужно два метода Measure
и MeasureOverride
, если Measure
вызывает MeasureOverride
? (аналогично для Arrange
)
Вызовы Add(Logical|Visual)Child
дают поддержку маршрутизации и наследования значений зависимых свойств? Связь между RenderSize
и availableSize
?
Когда наследоваться от FrameworkElement
, и когда от UIElement
?
Вызывается ли RenderSize
при создании объекта?
Зачем вызывать AddLogicalChild
для элемента который не будет обрабатывать событию и влиять на "логику"?
Как вообще элемент без OnRender
отрисовывает дочерние элементы?
Если HorizontalAlignment
и VerticalAlignment
= Center
, то availablesize
равен нулю, значит какое значение sizedesired
не верни, оно все равно урежется?
Пока не попытался все казалось таким простым и ясным... Есть какие-то общие, четкие правила когда и что нужно переопределять?
Вы понимаете вообще зачем вам нужно наследовать от FrameworkElement
?
А нужно это для создания собственных (кастомных) элементов управления. Наследуемый класс зависит от ваших задач:
FrameworkElement
когда нужно нарисовать его содержимое "с нуля" (с использованием DrawingContext
через переопределение OnRender
).UIElement
если желаете составить элемент из других контроловВообще, ответ на все вопросы есть тут: WPF layout: Measure и Arrange; а так же здесь: Understanding MeasureOverride and ArrangeOverride
А по повожу вашего нерабочего FrameworkElement
могу сказать следующее:
Как я уже сказал, FrameworkElement
рисуется "с нуля". Ну например:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Content = new MyFrameWorkElement();
}
}
public class MyFrameWorkElement : FrameworkElement
{
Size _size;
public MyFrameWorkElement()
{
this.SizeChanged += (o, e) =>
{
_size = e.NewSize;
this.InvalidateVisual(); // cause a render
};
}
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
drawingContext.DrawRectangle(
Brushes.Blue,
new Pen(Brushes.Red, 2),
new Rect(1, 1, _size.Width / 2, _size.Height / 2));
drawingContext.DrawEllipse(
Brushes.Green,
new Pen(Brushes.Yellow, 2),
center: new Point(_size.Width / 2, _size.Height / 2),
radiusX: _size.Width / 4,
radiusY: _size.Height / 4);
var txt = new FormattedText(
"Foobar",
System.Globalization.CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface("Courier new"),
21,
Brushes.Red);
drawingContext.DrawText(txt,
new Point(_size.Width / 2, _size.Height / 2)
);
}
}
Для создания собственных элементов управления я вообще использую UIElement
(и вам советую): UserControl.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Имеется 10 изображений в окне без рамки WPF формыКак мне их разместить так, чтобы можно было из другой формы растягивать сразу все изображения...
Как в переменную записать результат быстрейшего метода(два раза вызывается один метод с разными передаваемыми значениями, нужен результат...
С WebControl было то же самое, пока я не вставил его на формуЯ так понимаю, что он отключен, пока не находится на форме
andreycha почему то пометил предыдущую мою тему как дубликат, хотя решения в "ориджинал" теме для своей проблемы я не нашёл, вроде бы другая ситуация,...