1

我正在开发一个 C# WPF 组件(使用 VS2010 版本 10.0.40219.1 SP1Rel),其中包含 int 和 List 等公共属性。

该组件似乎可以通过 VS2010 wpf 编辑器进行序列化,因为 .xaml 中生成的 xml 块如下所示:

<Parent>
    <NumberProperty>10</NumberProperty>
    <ListProperty>
        <Item>
            blah
        </Item>
    </ListProperty>
</Parent>

当反序列化组件(即运行应用程序)时,会读取 List 属性(运行 getter)并将项目添加到其中。没有为列表运行设置器。

问题是列表包含故意的默认项目,该项目在项目父构造函数中添加到列表中。如果相关 xaml 中有可用的,这些/此预先存在的项目应替换为列表中的项目。

我尝试DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)作为列表属性没有运气。

那么是否可以通过环境的某些属性来判断它应该替换列表属性(调用设置器)而不是向其中添加项目?

4

2 回答 2

0

这是一个令人头疼的问题:)

正如您所说,如果您使用一些默认值初始化列表属性,它们不会出现在设计器中。如果您将一些值添加到列表中,它们会被序列化为 .xaml,然后这些值会在运行时添加到您的默认值中,而不是替换它们。

一种解决方案是使用一个自定义集合,该集合知道它包含一个(或多个)默认值,并在将第一个新项目添加到列表时将其(或它们)删除。

例如

public partial class UserControl1
{
    public UserControl1()
    {
        // initialise collection with '1' - doesn't appear in design time properties
        Ids = new MyCollection<int>(1);

        InitializeComponent();
    }

    public int Id { get; set; }

    public MyCollection<int> Ids { get; set; }
}

public class MyCollection<T> : Collection<T>
{
    private readonly T _defaultValue;
    private bool _hasDefaultValue;

    public MyCollection(T defaultValue)
    {
        _defaultValue = defaultValue;

        try
        {
            _hasDefaultValue = false;

            Add(defaultValue);
        }
        finally
        {
            _hasDefaultValue = true;
        }
    }

    protected override void InsertItem(int index, T item)
    {
        base.InsertItem(index, item);

        if (_hasDefaultValue)
        {
            Remove(_defaultValue);
            _hasDefaultValue = false;
        }
    }
}

Xaml

    <local:UserControl1 Id="5">
        <local:UserControl1.Ids>
            <System:Int32>2</System:Int32>
            <System:Int32>3</System:Int32>
            <System:Int32>4</System:Int32>
        </local:UserControl1.Ids>
    </local:UserControl1>

我不能说这是一个特别令人满意的解决方案,但我认为它确实解决了你的问题。

于 2012-10-16T22:29:32.507 回答
0

我知道这是一个老问题,很久以前就找到了一种解决方案,但无论如何。应该使用列表添加项目,因此列表将被替换。像这样:

<Parent>
<NumberProperty>10</NumberProperty>
<ListProperty>
    <List>
        <Item>
            blah
        </Item>
    </List>
</ListProperty>
于 2021-07-02T10:20:36.050 回答