代码之家  ›  专栏  ›  技术社区  ›  caryden

UserControl.InitializeComponent()中存在间歇性InavlidCastException异常

  •  2
  • caryden  · 技术社区  · 16 年前

    我有一个Silverlight控件库“Controls”,其中定义了一个用于显示对话框的客户控件:

    public class Dialog : ContentControl
    {
        public Dialog()
            : base()
        {
            DefaultStyleKey = typeof(Dialog);
        }
    
    <...normal custom control stuff...>
    }
    

    <Style TargetType="src_general:Dialog">
        <Setter Property="Padding" Value="25"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="src_general:Dialog">
                    <Grid x:Name="RootElement" >
                        <vsm:VisualStateManager.VisualStateGroups>
                            <vsm:VisualStateGroup x:Name="DiakogStyleStates">
                                <vsm:VisualState x:Name="OkCancel">
                                    <Storyboard>
                                    </Storyboard>
                                </vsm:VisualState>
                                <vsm:VisualState x:Name="OkOnly">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Duration="0:0:0" Storyboard.TargetName="CancelButton" Storyboard.TargetProperty="Visibility" >
                                            <DiscreteObjectKeyFrame KeyTime="0:0:0" >
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Collapsed</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </vsm:VisualState>
                                <vsm:VisualState x:Name="CancelOnly">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Duration="0:0:0" Storyboard.TargetName="OkButton" Storyboard.TargetProperty="Visibility" >
                                            <DiscreteObjectKeyFrame KeyTime="0:0:0" >
                                                <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Collapsed</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </vsm:VisualState>
                                <vsm:VisualState x:Name="None">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Duration="0:0:0" Storyboard.TargetName="CancelButton" Storyboard.TargetProperty="Visibility" >
                                            <DiscreteObjectKeyFrame KeyTime="0:0:0" >
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Collapsed</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                             <ObjectAnimationUsingKeyFrames Duration="0:0:0" Storyboard.TargetName="OkButton" Storyboard.TargetProperty="Visibility" >
                                            <DiscreteObjectKeyFrame KeyTime="0:0:0" >
                                                <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Collapsed</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </vsm:VisualState>
                            </vsm:VisualStateGroup>
                        </vsm:VisualStateManager.VisualStateGroups>
                             <Popup x:Name="DialogPopup">
                            <src_general:WindowFrame x:Name="Frame">
                                <Grid >
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="*" />
                                        <RowDefinition Height="Auto" />
                                    </Grid.RowDefinitions>
    
                                    <ContentPresenter Grid.Row="0" x:Name="ContentPresenter" Margin="{TemplateBinding Padding}"/>
                                         <!--Action Buttons-->
                                    <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right" Margin="15">
                                        <src_general:GlassButton x:Name="CancelButton" Content="Cancel" Margin="2"/>
                                        <src_general:GlassButton x:Name="OkButton" Content="Ok" Margin="2"/>
                                    </StackPanel>
                                </Grid>
    
                            </src_general:WindowFrame>
                        </Popup>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    我在很多地方使用这个对话框都没有问题。但是,在一个应用程序中,从RootVisual嵌套了大约3-4个usercontrols,我使用它的方式如下:

    <general:Dialog x:Name="AddUpdateDialog" DialogStyle="OkCancel" Title="Add/Update Connection" Closed="AddUpdateDialog_Closed" ValidationGroup="AddConnection">
                <Grid Width="300">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="10"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
    
                    <TextBlock Grid.Row="0" Grid.Column="0" Text="Name:" Style="{StaticResource LabelText}"/>
                    <TextBox Grid.Row="0" Grid.Column="2" Text="{Binding Name, Mode=TwoWay}" Style="{StaticResource TextBoxInput}" MaxLength="49">
                        <val:ValidationManager.Validator>
                            <val:RequiredValidator ManagerName="AddConnection" ErrorMessage="Name is required."/>
                        </val:ValidationManager.Validator>
                    </TextBox>
                </Grid>
            </general:Dialog>
    

    当我运行此应用程序时,我会间歇性(大约每5-10次启动)出现以下异常:

    “无法强制转换类型为的对象 System.Windows.Controls.ContentControl hookitupright.com.silverlight.controls.general.Dialog “发生在 InitializeComponent() 为父母 UserControl 对上述XAML的定义。

    this.AddUpdateDialog = ((hookitupright.com.silverlight.controls.general.Dialog)(this.FindName("AddUpdateDialog")));
    

    当我在那里放置断点时,大多数时候FindName返回对话框类型的对象,但有时返回ContentControl(对话框的基础)并失败。XAML没有改变。它是静态的…因为异常是间歇性的,并且发生在生成的代码中,所以我不知所措。

    我试过:

    1. 2a。考虑到这可能与文本框的双向绑定有关,我删除了绑定。仍然失败。

    更新:鉴于以上第(2)条,我把文本框注释掉了,决定继续讨论其他事情,并带着希望回到这个话题,希望有什么事情会向我展示自己。不幸的是,它似乎在文本框关闭时也会失败,只是频率较低。

    问题是它并非每次都失败。大约有20%的时间会爆炸。当它工作时,所有的东西都能工作,即使是这个对话框?

    如果不是同一个问题的话,这个问题是相关的:当我通过注释掉所需的功能来“修复”invalidcast时,我将不太频繁地但间歇性地得到它 this 无效的属性(当属性/属性实际存在时)。

    2 回复  |  直到 7 年前
        1
  •  1
  •   caryden    16 年前

    经过大量的研究和挫折,我相信这与此有关: http://blogs.msdn.com/silverlight_sdk/archive/2008/10/24/loaded-event-timing-in-silverlight.aspx

    我已经在上面的基础上修改了一些代码,现在它似乎没有失败。我希望我能确切地告诉你为什么它会这样做,为什么我会这样做来修复它(或者至少再次掩盖它??),但我不能。也许其他人会遇到这种情况,并能找到答案。

    以下是我所做的和我所改变的:

    好的,足够的背景知识。从文档中,我知道我只能在应用模板后访问TextBox样式的元素(新的visualStates和通知图标),因此我第一次连接到验证器的linkelement的已加载事件,并在那里调用Validate()。嗯,微软的某个人通过从WPF复制粘贴加载的事件描述,节省了大约15分钟,这让我心痛了大约3-4天。事实证明,无法保证在silverlight中的Loaded事件中应用该模板。因此,我只是在为linkedelement加载的事件处理程序中添加了对ApplyTemplate()的调用,失败就消失了。

    我的猜测是,错误是间歇性的,因为布局(以及模板的应用程序)是异步发生的,有时在我点击加载的事件时它就在那里,有时则不是。但我仍然认为这是一个Silverlight错误,因为错误出现在哪里,甚至可能指向一个安全漏洞(如果,但在代码中的其他地方,我可以导致XAML解析器返回与实际XAML指示的类型不同的类型…)。哦,好吧……它现在似乎起作用了。也许这会帮助其他人。

        2
  •  0
  •   Community    7 年前

    也许这对某人也有帮助:看看我的 answer