Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Silverlight嵌套自定义控件导致StackOverflowException_C#_Xaml_Silverlight_Controls_Stack Overflow - Fatal编程技术网

C# Silverlight嵌套自定义控件导致StackOverflowException

C# Silverlight嵌套自定义控件导致StackOverflowException,c#,xaml,silverlight,controls,stack-overflow,C#,Xaml,Silverlight,Controls,Stack Overflow,我正在为我的Silverlight项目编写一个可重用的Controllibrary。目前,每次启动使用Controllibrary的测试应用程序时,我都会收到一个StackOverflowException。我能够在一个小样本项目中重现异常 我有两个简单的自定义控件: //Control1.cs public class Control1:Control { public Control1() { this.DefaultStyleKey = typeof(Con

我正在为我的Silverlight项目编写一个可重用的Controllibrary。目前,每次启动使用Controllibrary的测试应用程序时,我都会收到一个StackOverflowException。我能够在一个小样本项目中重现异常

我有两个简单的自定义控件:

//Control1.cs
public class Control1:Control
{
    public Control1()
    {
        this.DefaultStyleKey = typeof(Control1);
    }
}

//Control2.cs
public class Control2:Control
{
    public static DependencyProperty TestProperty =  
            DependencyProperty.Register("Test",typeof(Control1),typeof(Control2),null);

    public Control1 Test
    {
        get {return (Control1)GetValue(TestProperty);}
        set {SetValue(TestProperty,value);}
    }

    public Control2()
    {
        this.DefaultStyleKey = typeof(Control2);
    }
}
//generic.xaml
<Style TargetType="local:Control1">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:Control1">
                <Rectangle Width="20" Height="20" Fill="Blue"/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style TargetType="local:Control2">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:Control2">
                <Rectangle Width="20" Height="20" Fill="Red"/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Test">
        <Setter.Value>
            <local:Control1/>
        </Setter.Value>
    </Setter>
</Style>
CONTROL2具有Control1类型的DependencyProperty。在我的Controllibrary中,Control1与菜单项类似,当按下Control2时,菜单项会被传递到菜单项。 现在,在my Themes/generic.xaml iam中,为控件定义了两种默认样式:

//Control1.cs
public class Control1:Control
{
    public Control1()
    {
        this.DefaultStyleKey = typeof(Control1);
    }
}

//Control2.cs
public class Control2:Control
{
    public static DependencyProperty TestProperty =  
            DependencyProperty.Register("Test",typeof(Control1),typeof(Control2),null);

    public Control1 Test
    {
        get {return (Control1)GetValue(TestProperty);}
        set {SetValue(TestProperty,value);}
    }

    public Control2()
    {
        this.DefaultStyleKey = typeof(Control2);
    }
}
//generic.xaml
<Style TargetType="local:Control1">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:Control1">
                <Rectangle Width="20" Height="20" Fill="Blue"/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style TargetType="local:Control2">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:Control2">
                <Rectangle Width="20" Height="20" Fill="Red"/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Test">
        <Setter.Value>
            <local:Control1/>
        </Setter.Value>
    </Setter>
</Style>
//generic.xaml
现在,当我在测试应用程序中使用Control2时,我得到一个StackOverflowException。设置断点时,将调用Control2的构造函数一次,然后继续调用Control1的构造函数,直到StackOverflowException

当我将Control1s构造函数更改为直接从带有resourceKey的ResourceDictionary加载其样式时,一切都可以正常加载。但这更像是一种变通办法,而不是解决方案

当我在generic.xaml中删除TestProperty的Setter时,一切都可以正常工作。然后,我可以覆盖测试应用程序的my App.xaml中的样式,并在那里定义TestProperty的Setter。但这也不是我想做的

没有人能解决这个问题吗? 或者某个人可以解释为什么它会这样


提前感谢

我自己也偶然发现了这一美妙的效果,结果是:

您不能在
ResourceDictionary
中实例化从
UIElement
派生的对象(您的行
正好尝试了这一点)(generic.xaml是其中之一),因为所述字典中的所有对象都必须是可共享的

记录在案。相关章节:

可共享类型和UIElement类型

资源字典是一种定义可共享类型和 这些类型在XAML中的值。并非所有类型或值都适用 从ResourceDictionary获取用法。欲了解更多关于 类型在Silverlight中被认为是可共享的,请参阅参考资料 字典

特别是,所有UIElement派生类型都不可共享,除非 它们来自于模板和模板在特定领域的应用 控件实例。不包括模板案例,需要UIElement 实例化后仅存在于对象树中的一个位置,以及 让UIElement可共享可能会违反这一点 原则

但是有一种治疗方法

将控件1包装在
数据模板中
,使控件1不会在
资源字典
中实例化,而是在实际实例化控件2时实例化

<Style TargetType="OuterControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="OuterControl">
                <StackPanel>
                    <TextBlock Text="Outer Hello World"/>
                    <ContentPresenter
                        Content="{TemplateBinding Content}"
                        ContentTemplate="{TemplateBinding ContentTemplate}"/>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <InnerControl/>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

这正是我想要的答案。谢谢