如何在自定义StackPanel中为特定自定义控件创建项目列表?

时间:2013-02-17 04:42:39

标签: c# wpf silverlight wpf-controls silverlight-5.0

我想创建一个派生自StackPanel的自定义StackPanel。但是要添加项目,我想创建一个特殊列表(可以使用List<>或ObservableCollection<>)。它应该是这样的,

<mc:MyStackPanel>
  <mc:MyStackPanel.Items>
    <mc:MyControl Content="A" />
    <mc:MyControl Content="B" />
    <mc:MyControl Content="C" />
  </mc:MyStackPanel.Items>
</mc:MyStackPanel>

不是这样的(目前这个有效),

<mc:MyStackPanel>
   <mc:MyControl Content="A" />
   <mc:MyControl Content="B" />
   <mc:MyControl Content="C" />
</mc:MyStackPanel>

我尝试使用ObservableCollection,如果我添加项目,它可以很好地工作。 intellisense也只显示了一个可以添加的MyControl。

现在,如何从集合中获取列表并将其添加到StackPanel,即使用stkPanel.Children.Add()。

我应该使用Panel还是如何获取列表并添加到Panel中?提前谢谢。

PS:我尝试了几个选项,但列表总是为null,包括使用ItemsControl。所以我可能在这里错过了一些观点。再次使用ItemsControl不适合我的场景,因为我只想要一个可以添加到面板的控件类型。

1 个答案:

答案 0 :(得分:0)

如何使用ObservableCollection的集合更改事件来保持Children属性同步?我还添加了ContentProperty属性,因此您无需在XAML中明确地向集合中添加项目,如果需要,可以将其删除。

[ContentProperty("CustomItems")]
public class MyCustomStackPanel : StackPanel
{
    public MyCustomStackPanel()
    {
        CustomItems = new ObservableCollection<MyUserControl>();
    }

    private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems != null)
        {
            foreach (object element in e.NewItems)
            {
                Children.Add((UIElement) element);
            }
        }

        if (e.OldItems != null)
        {
            foreach (object element in e.OldItems)
            {
                Children.Remove((UIElement)element);
            }
        }
    }

    private ObservableCollection<MyUserControl> _customItems;
    public ObservableCollection<MyUserControl> CustomItems
    {
        get { return _customItems; }
        set
        {
            if(_customItems == value)
                return;

            if (_customItems != null)
                _customItems.CollectionChanged -= OnCollectionChanged;

            _customItems = value;

            if (_customItems != null)
                _customItems.CollectionChanged += OnCollectionChanged;
        }
    }
}

然后XAML看起来像这样(本地命名空间指向自定义控件所在的项目)

<local:MyCustomStackPanel>
    <local:MyUserControl></local:MyUserControl>
</local:MyCustomStackPanel>