在 generic.xaml 中使用 Style Setter 设置 Control 类型的属性会导致 VS 崩溃

发布于 2024-11-09 14:52:55 字数 2801 浏览 4 评论 0原文

在 generic.xaml 的主控件 Style 中,我尝试设置主控件的属性的默认值(该属性的类型为 Control),但这会导致 VS 2010 在设计视图中使用 MyMainControl 时崩溃。使用下面的代码可以看出该问题。我使用的是Silverlight 4。我还尝试将MyControl指定为资源(如下面代码中注释掉的那样),这也导致VS 2010在使用MyMainControl时崩溃。

我发现,如果我在 MyControl 构造函数中删除“DefaultStyleKey = typeof(MyControl)”,则不会出现问题(但随后 MyControl 的样式不会应用于它,并且控件看起来不正确)。

这里的主要目标是,我需要允许 MyMainControl 类有选择地创建 MyControl 类的实例,以便在 MyMainControl 类的实例化期间设置 MyControl 属性。默认情况下,我希望将 MyControl 属性设置为 MyControl 的实例,但我希望用户能够在其 XAML 中为 MyControl 属性指定 null(或指定具有不同设置的 MyControl 实例),并且如果他们这样做,我希望 MyControl 的默认内部实例化不发生(以提高 MyMainControl 的效率)。

我最初在 MyMainControl 的构造函数中创建了 MyControl 实例,但是如果用户在 MyMainControl XAML 中将 MyControl 属性设置为 null,则仍然会在内部不必要地创建 MyControl 实例(然后用 null 覆盖),这会导致性能大幅下降(而不是仅仅使用 null 并且不在内部创建 MyControl)。

在 WPF 中,我能够将 MyControl 指定为资源,然后在 MyMainControl 的 generic.xaml 样式中,我能够将 MyControl 属性设置为 MyControl 类的实例,这极大地提高了 MyMainControl 的性能(如果用户将 MyControl 设置为 null。但我无法在 Silverlight 中实现同样的功能。

总而言之,主要思想是,如果我可以使用 MyMainControl 样式为 MyControl 属性指定默认值,那么用户将能够指定自己的 MyMainControl 样式,在其中可以指定MyControl 属性值为 null 或具有不同设置的 MyControl 实例 - 由于它们的 MyMainControl 样式将替换我的,因此我在 MyMainControl 样式中指定的默认 MyControl 实例将不会发生。

我非常感谢任何人就如何在 Silverlight 中完成此操作提供的任何帮助!

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyNamespace"
>

<Style TargetType="local:MyControl">
    <Setter Property="Opacity" Value="1" />
</Style>

<!-- Note: I tried specifying my control as a resource
(so I could in the MyMainControl style set the property to
the MyControl StaticResource), but include this line of XAML
causes VS 2010 to crash when using my main control.
<local:MyControl x:Key="MyControl" />-->

<Style TargetType="local:MyMainControl">
    <Setter Property="MyControl" >
        <Setter.Value>
            <local:MyControl />
        </Setter.Value>
    </Setter>
</Style>

MyControl 是一个非常简单的类,派生自 Control:

public class MyControl : Control
{
    public MyControl()
    {
        DefaultStyleKey = typeof(MyControl);
    }
}

MyMainControl MyControl DependencyProperty 的代码是:

public partial class MyMainControl : Control
{
...
    public static readonly DependencyProperty MyControlProperty = DependencyProperty.Register("MyControl", typeof(MyControl), typeof(MyMainControl), new PropertyMetadata(null));

    public MyControl MyControl
    {
        get
        {
            return (MyControl)GetValue(MyControlProperty);
        }
        set
        {
            SetValue(MyControlProperty, value);
        }
    }
}

In my main control Style in generic.xaml, I'm trying to set the default value of a property of my main control (and this property is of type Control), but this causes VS 2010 to crash when using MyMainControl in the design view. The issue can be seen using the code below. I'm using Silverlight 4. I also tried to specify MyControl as a resource (as shown commented out in the code below), and this also caused VS 2010 to crash when using MyMainControl.

I found that if I remove "DefaultStyleKey = typeof(MyControl)" in the MyControl constructor, then the issue does not occur (but then MyControl's style is not applied to it and the control does not look right).

The main goal here is that I need to allow the MyMainControl class to optionally create an instance of the MyControl class to set the MyControl property to during the instantiation of the MyMainControl class. By default, I want the MyControl property to be set to an instance of MyControl, but I want the user to be able to specify null (or specify an instance of MyControl with different settings) for the MyControl property, in their XAML, and if they do so, I want the default internal instantiation of MyControl to not take place (in order to improve the efficiency of MyMainControl).

I originally created the MyControl instance in the constructor of MyMainControl, but if the user sets the MyControl property to null in their MyMainControl XAML, the instance of MyControl is still needlessly created internally (and then overwritten with null), which results in much poorer performance (than just using null and not creating MyControl internally).

In WPF, I'm able to specify MyControl as a resource and then in the generic.xaml Style of MyMainControl I'm able to set the MyControl property to an instance of the MyControl class, which has greatly improved the performance of MyMainControl if the user sets MyControl to null. But I haven't been able to get the same to work in Silverlight.

In summary, the main idea is that if I can use the MyMainControl Style to specify a default value for the MyControl property, then the user will be able to specify their own MyMainControl Style in which they can specify for the MyControl property a value of null or an instance of MyControl with different settings--and since their MyMainControl Style will replace mine, then the default instantiation of MyControl that I specify in my MyMainControl Style will not occur.

I greatly appreciate any help anyone can provide on how this might be done in Silverlight!

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyNamespace"
>

<Style TargetType="local:MyControl">
    <Setter Property="Opacity" Value="1" />
</Style>

<!-- Note: I tried specifying my control as a resource
(so I could in the MyMainControl style set the property to
the MyControl StaticResource), but include this line of XAML
causes VS 2010 to crash when using my main control.
<local:MyControl x:Key="MyControl" />-->

<Style TargetType="local:MyMainControl">
    <Setter Property="MyControl" >
        <Setter.Value>
            <local:MyControl />
        </Setter.Value>
    </Setter>
</Style>

MyControl is a very simple class that derives from Control:

public class MyControl : Control
{
    public MyControl()
    {
        DefaultStyleKey = typeof(MyControl);
    }
}

The code for the MyMainControl MyControl DependencyProperty is:

public partial class MyMainControl : Control
{
...
    public static readonly DependencyProperty MyControlProperty = DependencyProperty.Register("MyControl", typeof(MyControl), typeof(MyMainControl), new PropertyMetadata(null));

    public MyControl MyControl
    {
        get
        {
            return (MyControl)GetValue(MyControlProperty);
        }
        set
        {
            SetValue(MyControlProperty, value);
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文