Изменение размера элемента пользовательского фреймворка в соответствии с родительским

#wpf #xaml

#wpf #xaml

Вопрос:

Я пытаюсь создать пользовательский объект элемента фреймворка. К сожалению, я не могу понять, как изменить его размер, чтобы он соответствовал родительскому (например, для границы).

У меня настроен конструктор, как показано ниже, но событие SizeChanged не вызывается (за исключением самого начала).

 public MyFrameworkElement()
{
    this.SizeChanged  = (o, e) =>
    {
        this.Width = e.NewSize.Width;
        this.Height = e.NewSize.Height;
        this.InvalidateVisual();
    };
}
  

Комментарии:

1. что вы пытаетесь сделать? если у вас нет чего-то нестандартного, нет причин прибегать к нестандартным методам. Пожалуйста, уточните

2. Мой класс пуст. Мой метод рисования просто рисует черный прямоугольник для справки. В данный момент я ничего не пытаюсь сделать, просто пытаюсь сначала заставить работать самые простые части.

3. Если вам нужен прямоугольник, просто сделайте <Rectangle/> в XAML. WPF — это не winforms. Опять же, если вам не нужно что-то very нестандартное, нет причин прибегать к нестандартным методам. WPF касается XAML и привязки данных, а не процедурного кода.

Ответ №1:

обычно вам приходится выполнять такой код в MeasureOverride и ArrangeOverride .

пример для MeasureOverride

 protected override Size MeasureOverride(Size availableSize)
{
    //return the available size to use the container size
    return availableSize;
}
  

при желании вы можете извлечь свой элемент из UserControl или другого подходящего контейнера, чтобы сделать это за вас.

дополнительная информация об измерении и упорядочивании здесь

http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.measureoverride

http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.arrangeoverride

если вы хотите использовать свой существующий код, это должно сработать, но не рекомендуется

     protected override void OnVisualParentChanged(DependencyObject oldParent)
    {
        base.OnVisualParentChanged(oldParent);
        if (oldParent != null)
            (oldParent as FrameworkElement).SizeChanged -= Parent_SizeChanged;
        if (Parent != null)
            (Parent as FrameworkElement).SizeChanged  = Parent_SizeChanged;
    }

    void Parent_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        this.Width = e.NewSize.Width;
        this.Height = e.NewSize.Height;
    }
  

Комментарии:

1. Я попытался установить для базового класса значение UserControl, но это ничего не изменило. Почему последнее — плохая идея?

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