C# 带有预先存在项的XAML列表值设置器

C# 带有预先存在项的XAML列表值设置器,c#,list,xaml,setter,C#,List,Xaml,Setter,我正在使用VS2010版本10.0.40219.1 SP1Rel开发一个C WPF组件,它包含int和List等公共属性 该组件似乎由VS2010 wpf编辑器序列化,因为.xaml中的结果xml块如下所示: <Parent> <NumberProperty>10</NumberProperty> <ListProperty> <Item> blah </It

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

该组件似乎由VS2010 wpf编辑器序列化,因为.xaml中的结果xml块如下所示:

<Parent>
    <NumberProperty>10</NumberProperty>
    <ListProperty>
        <Item>
            blah
        </Item>
    </ListProperty>
</Parent>
当反序列化组件(即运行应用程序)时,List属性为read runs getter,并向其添加项。没有为列表运行setter

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

我尝试了DesignerSerializationVisibility DesignerSerializationVisibility.Visible作为列表属性,但没有成功


因此,是否可以通过环境的某些属性来判断它应该替换列表属性调用setter而不是向其添加项?

这是一个令人头痛的问题:

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

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

e、 g

Xaml


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

谢谢:我有点担心它必须通过代码来完成。在我的例子中,对于最终用户透视图,最好添加一个内部构造函数,将“\u hasdaultvalue”设置为true,而其他构造函数则不设置。但这仍然会带来麻烦,因为我们无法判断无参数构造函数是由用户调用的还是由xaml加载器调用的。我不想更改容器,因为以前的版本已经在使用中。。我在list getter中尝试了类似的方法,如果组件还不够初始化,它会清空列表。需要进一步挖掘。
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;
        }
    }
}
    <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>