我正在制作Silverlight2 UserControl以模拟WinForms MessageBox的基本功能。我正在关注Shawn Wildermuth和John Papa's个例子。
编译好,我用一个按钮将用户控件添加到我的应用程序以显示弹出窗口。这样工作 - 弹出窗口出现,您可以单击按钮关闭它然后关闭。你可以多次这样做。
如果包含“MessageBox”的UserControl已关闭且创建了新的UserControl,则会出现此问题。如果您尝试在新实例上打开弹出窗口,则会抛出异常:
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 project to demonstrate the problem.测试平台有屏幕上的说明,告诉你如何重现这个问题。
这让我疯了,所以任何帮助或指示都会非常感激。
以下是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();
}
}
}
答案 0 :(得分:4)
您收到的实际错误消息如下:
如果您重构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);
}
}
答案 1 :(得分:2)
仅供参考,作为2009年3月发布的新Silverlight工具包的一部分,我们发布了一个Picker基类。 Picker类提供弹出功能,无需手动定位和显示弹出窗口。
如果您有兴趣,请给我一个大喊大叫,我会尽力在这里发布关于如何使用Picker的快速教程。 基本上是: