我正在尝试创建一个区域控件来执行以下操作
<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但我不确定如何正确分离它们。有什么建议吗?
答案 0 :(得分: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
});
}