Задать вопрос
Ogoun
@Ogoun
Programmer

WPF. Создание элементов из кода

Сделал свой базовый класс для последующего наследования от него окон. Все работает, но теперь хочу чтобы в нем создавались контролы, т.е. чтобы у наследников уже присутствовал к примеру StackPanel. При создании базового класса окна нельзя использовать XAML, т.е создание элемента нужно прописывать в коде. Как можно реализовать?
Пример для наглядности:
public partial class BaseToolPanel : Window
  {
    StackPanel stackPanel=new StackPanel();
    public BaseToolPanel()
    {
      stackPanel.Background=Brushes.Red;
      stackPanel.Name="spVidgets";
      //Делаю так, не отображается
      base.AddChild(stackPanel);
      base.AddVisualChild(stackPanel);
      base.AddLogicalChild(stackPanel);
    }
}
  • Вопрос задан
  • 10894 просмотра
Подписаться 6 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 2
kefirr
@kefirr
Все эти методы Add* — для других вещей, тебе они не нужны.
Window — это ContentControl. У него есть св-во Content, в которое и устанавливается содержимое. Содержимое — это один объект. Будь то Grid, StackPanel, что угодно. Поэтому просто так добавить что-то, чтобы оно уже было у наследников — не получится.

Проблема решается при помощи атрибута ContentProperty, который перенаправляет т.н. Direct Content (то, что задаётся в xaml) в указанную проперть.
Короче говоря, вот рабочий код:

  [ContentProperty("Child")]
  public class BaseWindow : Window
  {
   #region Fields and Constants

   public static readonly DependencyProperty ChildProperty =
     DependencyProperty.Register("Child", typeof (object), typeof (BaseWindow), new UIPropertyMetadata(0));

   #endregion

   #region Constructors

   public BaseWindow()
   {
     var rootStackPanel = new StackPanel();
     rootStackPanel.Children.Add(new Button {Content = "I'm button from base class"});
     var childContentControl = new ContentControl {DataContext = this};
     childContentControl.SetBinding(ContentProperty, "Child");
     rootStackPanel.Children.Add(childContentControl);
     Content = rootStackPanel;
   }

   #endregion

   #region Public properties and indexers

   public object Child
   {
     get { return GetValue(ChildProperty); }
     set { SetValue(ChildProperty, value); }
   }

   #endregion
  }


* This source code was highlighted with Source Code Highlighter.
Ответ написан
@asvishnyakov
Программист
Почему нельзя использовать XAML? Откуда такое идиотское ограничение?
Обычно это решается использованием Style / Control Template + переопределение ApplyTemplate, если нужно, например, подписаться на события у элемента управления.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы