ContentPresenter расширенного класса Window не показывает содержимое во время разработки

В настоящее время я пишу класс Dialog (незаметный элемент управления), который расширяет Window, и назначаю ControlTemplate по умолчанию этому классу с использованием стиля XAML.

Я хочу, чтобы раздел «Кнопки» в моем шаблоне диалогового окна можно было заменить, но предварительно заполнить его набором кнопок по умолчанию, если не указано иное. Вот почему я добавил в свой класс свойство зависимости с именем ButtonContent.

DefaultButtons (см. XAML ниже) отображаются правильно при запуске приложения, но предварительный просмотр дизайна Visual Studio 2010 не отображает содержимое. Почему этого не происходит?

Мой класс диалога выглядит так:

public class Dialog : Window
{
    public FrameworkElement ButtonContent
    {
        get { return (FrameworkElement)GetValue(ButtonContentProperty); }
        set { SetValue(ButtonContentProperty, value); }
    }

    public static readonly DependencyProperty ButtonContentProperty =
        DependencyProperty.Register("ButtonContent", typeof(FrameworkElement), typeof(Dialog), new UIPropertyMetadata(null));

    static Dialog()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(Dialog), new FrameworkPropertyMetadata(typeof(Dialog)));
    }
}

Это мой XAML:

<Style TargetType="{x:Type Dialogs:Dialog}">
    <Setter Property="DataContext" Value="{Binding RelativeSource={RelativeSource Self}}"/>     
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Dialogs:Dialog}">
                <StackPanel>
                    <ContentPresenter Content="{TemplateBinding ButtonContent}"/>
                    <TextBlock>This text is rendered correctly</TextBlock>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

    <Setter Property="ButtonContent">
        <Setter.Value>
            <!-- This stuff here is not shown in VS2010's preview -->
            <UniformGrid Name="DefaultButtons" Rows="1" Columns="2">
                <Button>Button 1</Button>
                <Button>Button 2</Button>
            </UniformGrid>
        </Setter.Value>
    </Setter>
</Style>

Когда я запускаю приложение, оно выглядит так:

Как обработано приложением

Дизайнер VS2010 отображает это:

Как обработано VS2010


Изменить: Как описано в комментариях, размещение указанного выше стиля в Themes \ Generic.xaml вместо моего словаря ресурсов, включенного в App.xaml, ничего не меняет.


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

<Dialogs:Dialog x:Class="Dialogs.TestDialog"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Dialogs="clr-namespace:Dialogs">
    <Dialogs:Dialog.ButtonContent>
        <Button>Also not shown at design time</Button>
    </Dialogs:Dialog.ButtonContent>
</Dialogs:Dialog> 

Изменить 3: если я добавлю свойство ButtonContent в UserControl вместо моего Dialog класса, который расширяет Window, ButtonContent будет правильно отображаться в пользовательском элементе управления ... Кроме того, VS2010, похоже, применяет стиль, определенный выше в любое окно, а не только окна класса Dialog, хотя я правильно установил TargetType ... странно!


person tlind    schedule 30.10.2012    source источник
comment
Когда вы говорите, что это мой xaml, вы имеете в виду generic.xaml? Обычно туда следует поместить стиль по умолчанию.   -  person dowhilefor    schedule 30.10.2012
comment
Дизайнер не отображает код, только XAML.   -  person Bob.    schedule 30.10.2012
comment
@dowhilefor: я поместил его в отдельный XAML, который был включен в MergedDictionary в моем App.xaml. Я также попытался поместить стиль диалога по умолчанию в Generic.xaml, как вы предложили. Во время выполнения это ничего не изменило; однако во время разработки этот стиль, по-видимому, вообще не применялся, так что это даже хуже, чем мой предыдущий подход.   -  person tlind    schedule 31.10.2012
comment
@Bob: Но, очевидно, дизайнер поддерживает это для элементов управления, поставляемых с WPF по умолчанию (таких как ContentControl или HeaderContentControl). В противном случае дизайнер не смог бы отображать содержимое кнопки или заголовок элементов вкладки. Кроме того, у меня действительно не так много кода - за исключением статического объявления свойства зависимости !?   -  person tlind    schedule 31.10.2012
comment
В противном случае дизайнер не отобразил бы содержимое кнопки или заголовок элементов вкладки. На вашем рисунке показан только TextBlock, отображаемый в VS Designer. Время выполнения отличается от того, что показано в конструкторе.   -  person Bob.    schedule 31.10.2012
comment
Я говорю о том, что должен быть способ отобразить недостающий контент, поскольку это удается другим элементам управления WPF. Возьмем, к примеру, GroupBox (специализация HeaderedContentControl): он позволяет мне устанавливать как его Content, так и Header (= свойство зависимости), и оба сразу отображаются в дизайнере.   -  person tlind    schedule 31.10.2012
comment
Как описано выше, кажется, имеет значение, делаю ли я все это в пользовательском классе, расширяющем Window, или в UserControl.   -  person tlind    schedule 31.10.2012


Ответы (1)


Я открыл отчет об ошибке в Microsoft Connect. по этому вопросу. Согласно MS, это известная проблема, и она вызвана следующим образом:

Спасибо, что сообщили об этой проблеме. С нашей стороны это известная проблема, и она возникла специально. Мы не можем создать экземпляр Window в дизайнере, поэтому заменяем его собственным прокси-типом. Вот почему он правильно работает в UserControl, а не в окне. Обходной путь - разработать содержимое диалогового окна отдельно как UserControl.

person tlind    schedule 14.11.2012