0

我正在尝试创建一个执行以下技巧的区域控件

<wgc:RegionContentControl Region="HotDog">
    <Label>Foo</Label>
    <Label>Bar</Label>
</wgc:RegionContentControl>

<wgc:RegionControl Region="HotDog">
</wgc:RegionControl>

在运行时和设计时,RegionContentControl 中定义的控件将附加到 RegionControl。例如,我可以使用它来将东西注入状态栏。

无论如何,在运行时它工作正常,有时在设计器中它工作。但是有时在设计器中我会收到一个错误

Element already has a logical parent. It must be detached from the
old parent before it is attached to the new one.

我实现上述模式的代码如下。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace My.Controls
{
    public class RegionMessage {
        public enum RegionAction {
            Add,
            Remove,
        }
        public string Region { get; set; }
        public List<Control> Controls { get; set; }
        public RegionAction Action { get; set; }
    }

    public class RegionControl : ItemsControl
    {
        public RegionControl()
        {
            ReactiveUI
                .MessageBus.Current
                .Listen<RegionMessage>()
                .Subscribe(HandleRegionMessage);
        }



        public string Region
        {
            get { return (string)GetValue(RegionProperty); }
            set { SetValue(RegionProperty, value); }
        }

        public static readonly DependencyProperty RegionProperty =
            DependencyProperty.Register("Region", typeof(string), typeof(RegionControl), new PropertyMetadata(""));


        private void HandleRegionMessage(RegionMessage obj)
        {
            if (obj.Region!=Region)
            {
                return;
            }
            if (obj.Action==RegionMessage.RegionAction.Add)
            {
                foreach (var item in obj.Controls)
                {
                    this.Items.Add(item);
                }
            }
            else
            {
                foreach (var item in obj.Controls)
                {
                    this.Items.Remove(item);
                }

            }
        }
    }

    [ContentProperty("Children")]
    public class RegionContentControl : Control
    {
        static RegionContentControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(RegionContentControl), new FrameworkPropertyMetadata(typeof(RegionContentControl)));
        }

        public static readonly DependencyProperty ChildrenProperty =
       DependencyProperty.Register("Children", typeof(List<Control>), typeof(RegionContentControl), new PropertyMetadata(new List<Control>()));

        public List<Control> Children
        {
            get { return (List<Control>)GetValue(ChildrenProperty); }
            set { SetValue(ChildrenProperty, value); }
        }

        public string Region
        {
            get { return (string)GetValue(RegionProperty); }
            set { SetValue(RegionProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Region.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RegionProperty =
            DependencyProperty.Register("Region", typeof(string), typeof(RegionContentControl), new PropertyMetadata(""));



        public RegionContentControl()
        {
            this.LoadedObserver().Subscribe(Loaded);
        }

        private void Loaded(System.Reactive.EventPattern<RoutedEventArgs> obj)
        {
            ReactiveUI.MessageBus.Current.SendMessage(new RegionMessage()
            {
                Action = RegionMessage.RegionAction.Add
                ,
                Controls = Children
                ,
                Region = Region
            });
        }
    }

}

我确信我的问题涉及控件仍然认为它们附加到 RegionContentControl 但我不确定如何正确分离它们。有什么建议么?

4

1 回答 1

0

在广播之前从儿童中删除项目就可以了

    List<Control> _HiddenChildren;

    private void Loaded(System.Reactive.EventPattern<RoutedEventArgs> obj)
    {
        if (_HiddenChildren==null)
        {
            _HiddenChildren = Children;
            this.Children = new List<Control>();
        }

        ReactiveUI.MessageBus.Current.SendMessage(new RegionMessage()
            { Action = RegionMessage.RegionAction.Add
            , Controls = _HiddenChildren
            , Region = Region
            });
    }
于 2013-05-22T10:28:51.813 回答