Silverlight Popup UserControl - работает один раз, затем вылетает - PullRequest
1 голос
/ 18 марта 2009

Я собираюсь создать пользовательский элемент управления Silverlight2 для эмуляции основных функций WinBorm MessageBox. Я следовал за Шоном Вильдермутом и примерами Джона Папы.

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

Проблема возникает, если пользовательский элемент управления, содержащий MessageBox, закрыт и создан новый. Если вы попытаетесь открыть всплывающее окно на новом экземпляре, оно выдаст исключение:

Unhandled Error in Silverlight 2 Application
Code: 4004
Category: ManagedRuntimeError
Message: System.ArgumentException: Value does not fall within the expected range.
  at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
  at MS.Internal.XcpImports.FrameworkElement_MeasureOverride(FrameworkElement element, Size availableSize)
  at System.Windows.FrameworkElement.MeasureOverride(Size availableSize)
  ...
  (stack trace doesnt go as far as any of my code)

Код для управления находится внизу поста. Если вы хотите запустить его, я создал проект testbench, чтобы продемонстрировать проблему. Testbench имеет инструкции на экране, чтобы рассказать, как воспроизвести проблему.

Это сводит меня с ума, поэтому любая помощь или указатели будут с благодарностью.

Вот код для пользовательского элемента управления PopupMessage:

<UserControl x:Class="SilverlightPopupControlTest.PopupMessage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows" 
    >
    <Grid x:Name="LayoutRoot">

        <vsm:VisualStateManager.VisualStateGroups>
            <vsm:VisualStateGroup x:Name="PopupState" CurrentStateChanged="PopupState_CurrentStateChanged">
                <vsm:VisualStateGroup.Transitions>
                    <vsm:VisualTransition GeneratedDuration="00:00:00.2000000"/>
                    <vsm:VisualTransition GeneratedDuration="00:00:00.2000000" To="PopupStateOpened"/>
                    <vsm:VisualTransition GeneratedDuration="00:00:00.2000000" To="PopupStateClosed"/>
                </vsm:VisualStateGroup.Transitions>
                <vsm:VisualState x:Name="PopupStateClosed">
                    <Storyboard>
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="PopupFillGrid" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#00FFFFFF"/>
                        </ColorAnimationUsingKeyFrames>
                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
                            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.5"/>
                        </DoubleAnimationUsingKeyFrames>
                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
                            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.5"/>
                        </DoubleAnimationUsingKeyFrames>
                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.Opacity)">
                            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </vsm:VisualState>
                <vsm:VisualState x:Name="PopupStateOpened">
                    <Storyboard>
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="PopupFillGrid" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#BFFFFFFF"/>
                        </ColorAnimationUsingKeyFrames>
                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
                            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
                        </DoubleAnimationUsingKeyFrames>
                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
                            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
                        </DoubleAnimationUsingKeyFrames>
                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.Opacity)">
                            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </vsm:VisualState>
            </vsm:VisualStateGroup>
        </vsm:VisualStateManager.VisualStateGroups>

        <Popup x:Name="PopupControl">
            <Grid x:Name="PopupFillGrid">
                <Grid.Background>
                    <SolidColorBrush Color="#00ffffff"/>
                </Grid.Background>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>

                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition/>
                </Grid.RowDefinitions>

                <Border Grid.Row="1" Grid.Column="1" RenderTransformOrigin="0.5,0.5" x:Name="border" Opacity="0" >
                    <Border.RenderTransform>
                        <TransformGroup>
                            <ScaleTransform ScaleX="0.5" ScaleY="0.5"/>
                            <SkewTransform/>
                            <RotateTransform/>
                            <TranslateTransform/>
                        </TransformGroup>
                    </Border.RenderTransform>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="40"/>
                        </Grid.RowDefinitions>

                        <ContentPresenter x:Name="PopupContentPresenter"/>

                        <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
                            <Button x:Name="Button1" Click="Button1_Click" Margin="4" MinWidth="80">
                                <ContentPresenter x:Name="Button1ContentPresenter"/>
                            </Button>
                            <Button x:Name="Button2" Click="Button2_Click" Margin="4" MinWidth="80">
                                <ContentPresenter x:Name="Button2ContentPresenter"/>
                            </Button>
                            <Button x:Name="Button3" Click="Button3_Click"  Margin="4" MinWidth="80">
                                <ContentPresenter x:Name="Button3ContentPresenter"/>
                            </Button>
                        </StackPanel>
                    </Grid>
                </Border>
            </Grid>
        </Popup>
    </Grid>
</UserControl>

и его код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightPopupControlTest
{
    public partial class PopupMessage : UserControl
    {
        #region PopupContent Dependency Property
        public UIElement PopupContent
        {
            get { return (UIElement)GetValue(PopupContentProperty); }
            set { SetValue(PopupContentProperty, value); }
        }
        public static readonly DependencyProperty PopupContentProperty = DependencyProperty.Register(
            "PopupContent", typeof(UIElement), typeof(PopupMessage), new PropertyMetadata(PopupContentChanged));

        private static void PopupContentChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            ((PopupMessage)o).OnPopupContentChanged((UIElement)e.OldValue, (UIElement)e.NewValue);
        }

        private void OnPopupContentChanged(UIElement oldValue, UIElement newValue)
        {
            this.PopupContentPresenter.Content = newValue;
        }
        #endregion
        #region Button1Visibility Dependency Property
        public Visibility Button1Visibility
        {
            get { return (Visibility)GetValue(Button1VisibilityProperty); }
            set { SetValue(Button1VisibilityProperty, value); }
        }
        public static readonly DependencyProperty Button1VisibilityProperty = DependencyProperty.Register(
            "Button1Visibility", typeof(Visibility), typeof(PopupMessage), new PropertyMetadata(Button1VisibilityChanged));


        private static void Button1VisibilityChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            ((PopupMessage)o).OnButton1VisibilityChanged((Visibility)e.OldValue, (Visibility)e.NewValue);
        }

        private void OnButton1VisibilityChanged(Visibility oldValue, Visibility newValue)
        {
            this.Button1.Visibility = newValue;
        }
        #endregion
        #region Button2Visibility Dependency Property
        public Visibility Button2Visibility
        {
            get { return (Visibility)GetValue(Button2VisibilityProperty); }
            set { SetValue(Button2VisibilityProperty, value); }
        }
        public static readonly DependencyProperty Button2VisibilityProperty = DependencyProperty.Register(
            "Button2Visibility", typeof(Visibility), typeof(PopupMessage), new PropertyMetadata(Button2VisibilityChanged));

        private static void Button2VisibilityChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            ((PopupMessage)o).OnButton2VisibilityChanged((Visibility)e.OldValue, (Visibility)e.NewValue);
        }

        private void OnButton2VisibilityChanged(Visibility oldValue, Visibility newValue)
        {
            this.Button2.Visibility = newValue;
        }
        #endregion
        #region Button3Visibility Dependency Property
        public Visibility Button3Visibility
        {
            get { return (Visibility)GetValue(Button3VisibilityProperty); }
            set { SetValue(Button3VisibilityProperty, value); }
        }
        public static readonly DependencyProperty Button3VisibilityProperty = DependencyProperty.Register(
            "Button3Visibility", typeof(Visibility), typeof(PopupMessage), new PropertyMetadata(Button3VisibilityChanged));


        private static void Button3VisibilityChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            ((PopupMessage)o).OnButton3VisibilityChanged((Visibility)e.OldValue, (Visibility)e.NewValue);
        }

        private void OnButton3VisibilityChanged(Visibility oldValue, Visibility newValue)
        {
            this.Button3.Visibility = newValue;
        }
        #endregion
        #region Button1Content Dependency Property
        public UIElement Button1Content
        {
            get { return (UIElement)GetValue(Button1ContentProperty); }
            set { SetValue(Button1ContentProperty, value); }
        }
        public static readonly DependencyProperty Button1ContentProperty = DependencyProperty.Register(
            "Button1Content", typeof(UIElement), typeof(PopupMessage), new PropertyMetadata(Button1ContentChanged));

        private static void Button1ContentChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            ((PopupMessage)o).OnButton1ContentChanged((UIElement)e.OldValue, (UIElement)e.NewValue);
        }

        private void OnButton1ContentChanged(UIElement oldValue, UIElement newValue)
        {
            this.Button1ContentPresenter.Content = newValue;
        }
        #endregion
        #region Button2Content Dependency Property
        public UIElement Button2Content
        {
            get { return (UIElement)GetValue(Button2ContentProperty); }
            set { SetValue(Button2ContentProperty, value); }
        }
        public static readonly DependencyProperty Button2ContentProperty = DependencyProperty.Register(
            "Button2Content", typeof(UIElement), typeof(PopupMessage), new PropertyMetadata(Button2ContentChanged));


        private static void Button2ContentChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            ((PopupMessage)o).OnButton2ContentChanged((UIElement)e.OldValue, (UIElement)e.NewValue);
        }

        private void OnButton2ContentChanged(UIElement oldValue, UIElement newValue)
        {
            this.Button2ContentPresenter.Content = newValue;
        }
        #endregion
        #region Button3Content Dependency Property
        public UIElement Button3Content
        {
            get { return (UIElement)GetValue(Button3ContentProperty); }
            set { SetValue(Button3ContentProperty, value); }
        }
        public static readonly DependencyProperty Button3ContentProperty = DependencyProperty.Register(
            "Button3Content", typeof(UIElement), typeof(PopupMessage), new PropertyMetadata(Button3ContentChanged));

        private static void Button3ContentChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            ((PopupMessage)o).OnButton3ContentChanged((UIElement)e.OldValue, (UIElement)e.NewValue);
        }

        private void OnButton3ContentChanged(UIElement oldValue, UIElement newValue)
        {
            this.Button3ContentPresenter.Content = newValue;
        }
        #endregion

        public enum PopupMessageResult
        {
            Unknown=0,
            Button1=1,
            Button2,
            Button3
        }

        #region PopupMessageClosed Event
        public class PopupMessageClosedEventArgs : EventArgs
        {
            public PopupMessage.PopupMessageResult Result { get; set; }

            public PopupMessageClosedEventArgs()
            {
            }

            public PopupMessageClosedEventArgs(PopupMessage.PopupMessageResult _Result)
            {
                this.Result = _Result;
            }

        }

        public delegate void PopupMessageClosedEventHandler(object sender, PopupMessageClosedEventArgs e);

        public event PopupMessageClosedEventHandler PopupMessageClosed;

        protected virtual void OnPopupMessageClosed(PopupMessageClosedEventArgs e)
        {
            if (PopupMessageClosed != null)
            {
                PopupMessageClosed(this, e);
            }
        }
        #endregion

        private PopupMessageResult m_Result = PopupMessageResult.Unknown;
        public PopupMessageResult Result
        {
            get { return m_Result; }
            set { m_Result = value; }
        }

        private FrameworkElement m_HostControl = null;
        public FrameworkElement HostControl
        {
            get { return m_HostControl; }
            set { m_HostControl = value; }
        }

        public PopupMessage()
        {
            InitializeComponent();

            this.Button1Visibility = Visibility.Collapsed;
            this.Button2Visibility = Visibility.Collapsed;
            this.Button3Visibility = Visibility.Collapsed;

            VisualStateManager.GoToState(this, "PopupStateClosed", false);
        }

        private void Close()
        {
            VisualStateManager.GoToState(this, "PopupStateClosed", true);
        }

        public void Show()
        {

            this.PopupControl.IsOpen = true;
            this.Visibility = Visibility.Visible;
            this.TabNavigation = KeyboardNavigationMode.Cycle;
            this.Button1.Focus();

            VisualStateManager.GoToState(this, "PopupStateOpened", true);
        }

        void PopupState_CurrentStateChanged(object sender, VisualStateChangedEventArgs e)
        {
            if (e.NewState.Name == "PopupStateClosed")
            {
                this.PopupControl.IsOpen = false;
                this.Visibility = Visibility.Collapsed;

                this.OnPopupMessageClosed(new PopupMessageClosedEventArgs(this.Result));
            }
        }

        private void Button1_Click(object sender, RoutedEventArgs e)
        {
            this.Result = PopupMessageResult.Button1;
            this.Close();
        }

        private void Button2_Click(object sender, RoutedEventArgs e)
        {
            this.Result = PopupMessageResult.Button2;
            this.Close();
        }

        private void Button3_Click(object sender, RoutedEventArgs e)
        {
            this.Result = PopupMessageResult.Button3;
            this.Close();
        }
    }
}

Ответы [ 2 ]

4 голосов
/ 18 марта 2009

Фактическое сообщение об ошибке, которое вы получаете, выглядит следующим образом:

alt text

Если вы выполните рефакторинг Page.xaml.cs, чтобы он выглядел следующим образом, это исправит вашу ошибку:

public partial class Page : UserControl
{
    private PopupHost popupHost1 = new PopupHost();

    public Page()
    {
        InitializeComponent();
    }

    private void OpenButton_Click(object sender, RoutedEventArgs e)
    {
        this.PageContent.Children.Add(popupHost1);
    }

    private void CloseButton_Click(object sender, RoutedEventArgs e)
    {
        this.PageContent.Children.Remove(popupHost1);
    }
}
2 голосов
/ 24 марта 2009

К вашему сведению, в рамках нового выпуска Silverlight Toolkit March 2009 мы выпустили базовый класс Picker. Этот класс Picker предоставляет функциональность всплывающих окон без необходимости вручную размещать и отображать всплывающие окна.

Если вам интересно, напишите мне, и я сделаю все возможное, чтобы опубликовать краткий учебник о том, как использовать Picker. В основном:

  1. Создать класс, который наследуется от Picker
  2. В Blend отредактируйте шаблон элемента управления
    1. Внутри всплывающего окна в шаблоне поместите все, что хотите, во всплывающем окне (например, кнопки или что-то в этом роде)
    2. Рядом с кнопкой-переключателем в шаблоне поместите любую визуализацию, которую вы хотите продемонстрировать, когда значение всплывающего окна закрыто.
  3. Expose TemplateParts для элементов, которые вы создаете в 2.1 и 2.2.
  4. в OnApplyTemplate захватывает экземпляры этих TemplateParts с GetTemplatePart
  5. Регистрация событий на этих элементах управления, чтобы реагировать на их изменения и обновлять элемент управления.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...