OnApplyTemplate не вызывается - PullRequest
2 голосов
/ 06 октября 2010

У меня есть решение с 2 проектами: приложение для Windows Phone и библиотека классов Windows Phone. В библиотеке классов есть элемент управления MessageBoxExtended, который наследуется от ContentControl. В проекте также есть папка Themes с файлом generic.xaml. В файле для Build Action установлено значение Page, и оно выглядит так:

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:KontactU.Common.WPControls;assembly=KontactU.Common.WPControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   
mc:Ignorable="d">
<Style TargetType="local:MessageBoxExtended">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:MessageBoxExtended">
                <Grid x:Name="LayoutRoot">
                <StackPanel>
                        <TextBlock x:Name="lblTitle" Text="Title Goes Here" Style="{StaticResource PhoneTextTitle3Style}"/>
                        <TextBlock x:Name="lblMessage" Text="Some long message here repeated over and over again. Some long message here repeated over and over again. " TextWrapping="Wrap" Style="{StaticResource PhoneTextNormalStyle}" />
                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                            <Button x:Name="btnLeft" Content="Button1" Click="btnLeft_Click"></Button>
                            <Button x:Name="btnCenter" Content="Button2" Click="btnCenter_Click"></Button>
                            <Button x:Name="btnRight" Content="Button3" Click="btnRight_Click"></Button>
                        </StackPanel>
                    </StackPanel>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Контрольный код выглядит так:

 public class MessageBoxExtended : ContentControl
{
    private TextBlock lblTitle;
    private TextBlock lblMessage;
    private Button btnLeft;
    private Button btnCenter;
    private Button btnRight;

    private bool currentSystemTrayState;

    internal Popup ChildWindowPopup
    {
        get;
        private set;
    }

    private static PhoneApplicationFrame RootVisual
    {
        get
        {
            return Application.Current == null ? null : Application.Current.RootVisual as PhoneApplicationFrame;
        }
    }

    public MessageBoxExtended()
        : base()
    {
        DefaultStyleKey = typeof(MessageBoxExtended);
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        lblTitle = this.GetTemplateChild("lblTitle") as TextBlock;
        lblMessage = this.GetTemplateChild("lblMessage") as TextBlock;
        btnLeft = this.GetTemplateChild("btnLeft") as Button;
        btnCenter = this.GetTemplateChild("btnCenter") as Button;
        btnRight = this.GetTemplateChild("btnRight") as Button;

        InitializeMessageBoxExtended("Title", "Message", MessageBoxExtendedButtonType.Ok);
    }

    private void InitializeMessageBoxExtended(string title, string message, MessageBoxExtendedButtonType buttonType)
    {
        HideSystemTray();
        lblTitle.Text = title;
        lblMessage.Text = message;

        switch (buttonType)
        {
            case MessageBoxExtendedButtonType.Ok:
                btnLeft.Visibility = System.Windows.Visibility.Collapsed;
                btnRight.Visibility = System.Windows.Visibility.Collapsed;
                btnCenter.Content = "ok";
                break;
            case MessageBoxExtendedButtonType.OkCancel:
                btnCenter.Visibility = System.Windows.Visibility.Collapsed;
                btnLeft.Content = "ok";
                btnRight.Content = "cancel";
                break;
            case MessageBoxExtendedButtonType.YesNo:
                btnCenter.Visibility = System.Windows.Visibility.Collapsed;
                btnLeft.Content = "yes";
                btnRight.Content = "no";
                break;
        }
    }

    public void Show(string title, string message, MessageBoxExtendedButtonType buttonType)
    {
        if (ChildWindowPopup == null)
        {
            ChildWindowPopup = new Popup();

            try
            {
                ChildWindowPopup.Child = this;
            }
            catch (ArgumentException)
            {
                throw new InvalidOperationException("The control is already shown.");
            }
        }

        if (ChildWindowPopup != null && Application.Current.RootVisual != null)
        {
            // Configure accordingly to the type
            InitializeMessageBoxExtended(title, message, buttonType);

            // Show popup
            ChildWindowPopup.IsOpen = true;
        }
    }

    private void HideSystemTray()
    {
        // Capture current state of the system tray
        this.currentSystemTrayState = SystemTray.IsVisible;
        // Hide it
        SystemTray.IsVisible = false;
    }
}

Приложение для Windows Phone ссылается на него и вызывает его в коде, создав его экземпляр и вызвав метод Show:

MessageBoxExtended mbe = new MessageBoxExtended();
mbe.Show();

Проблема в том, что OnApplyTemplate никогда не вызывается. Я попытался закомментировать все строки в generic.xaml, но я получил тот же результат.

Есть идеи?

1 Ответ

1 голос
/ 07 октября 2010

Неважно, это была моя ошибка. Я добавил

if (lblTitle == null)
            return;

в метод InitializeMessageBoxExtended (), и теперь он работает. Если вы следуете логике, конструктор вызывается перед OnApplyTemplate (), который вызывает InitializeMessageBoxExtended (), и, следовательно, значения равны нулю. При добавлении кода над элементом управления не генерируется исключение, оно продолжается, и когда элемент управления является частью VisualTree, вызывается OnApplyTemplate.

Надеюсь, это кому-нибудь поможет.

...