简单的 ParentAdapter 实现是什么样的?
我正在尝试编写一个 ParentAdapter
实现; 我有兴趣为我正在编写的一些 WPF 控件提供设计时支持,这就是管理自定义逻辑以将项目重新设置为不同容器控件的方法。 我从小处开始,想法是创建一个 StackPanel
派生类,该类只允许 Button
元素在设计时成为父级(是的,我知道面板它本身也需要代码来支持这一点。)我从我认为最简单的 ParentAdapter
开始:
using System;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Windows.Design.Interaction;
using Microsoft.Windows.Design.Model;
namespace ControlLibrary.Design
{
internal class SimplePanelParentAdapter : ParentAdapter
{
public override bool CanParent(ModelItem parent, Type childType)
{
return (childType == typeof(Button));
}
// moves the child item into the target panel; in this case a SimplePanel
public override void Parent(ModelItem newParent, ModelItem child)
{
using (ModelEditingScope undoContext = newParent.BeginEdit())
{
// is this correct?
//child.Content.SetValue("I'm in a custom panel!");
SimplePanel pnl = newParent.GetCurrentValue() as SimplePanel;
pnl.Children.Add(child.GetCurrentValue() as UIElement);
undoContext.Complete();
}
}
public override void RemoveParent(ModelItem currentParent, ModelItem newParent, ModelItem child)
{
// No special things need to be done, right?
child.Content.SetValue("I was in a custom panel.");
}
}
}
当我在设计时使用它时,只要我将一个按钮拖到上面在我的自定义面板中,VS 代码深处抛出了一个 NullReferenceException
。 我的代码没有抛出异常,因为我可以一路单步执行我的方法; 调用堆栈表明 Microsoft.Windows.Design.Developer.dll 中的代码正在引发异常。
显然我做错了一些事情,但是文档没有提供任何示例,而且我的 search-fu 似乎表明要么没有人尝试这个,要么任何尝试它的人都没有谈论它。 有人有建议吗?
I'm trying to write a ParentAdapter
implementation; I'm interested in providing design-time support for some WPF controls I'm writing and this is how you manage custom logic for reparenting items to different container controls. I started small, with the notion of creating a StackPanel
-derived class that would only allow Button
elements to be parented at design-time (yes, I'm aware the panel itself needs code to support this as well.) I started with what I figured would be the simplest the ParentAdapter
could be:
using System;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Windows.Design.Interaction;
using Microsoft.Windows.Design.Model;
namespace ControlLibrary.Design
{
internal class SimplePanelParentAdapter : ParentAdapter
{
public override bool CanParent(ModelItem parent, Type childType)
{
return (childType == typeof(Button));
}
// moves the child item into the target panel; in this case a SimplePanel
public override void Parent(ModelItem newParent, ModelItem child)
{
using (ModelEditingScope undoContext = newParent.BeginEdit())
{
// is this correct?
//child.Content.SetValue("I'm in a custom panel!");
SimplePanel pnl = newParent.GetCurrentValue() as SimplePanel;
pnl.Children.Add(child.GetCurrentValue() as UIElement);
undoContext.Complete();
}
}
public override void RemoveParent(ModelItem currentParent, ModelItem newParent, ModelItem child)
{
// No special things need to be done, right?
child.Content.SetValue("I was in a custom panel.");
}
}
}
When I work with this at design-time, as soon as I drag a button over my custom panel, a NullReferenceException
is thrown from deep within the VS code. My code is not throwing the exception, because I can step all the way through my method; the call stack indicates that code in Microsoft.Windows.Design.Developer.dll is throwing the exception.
Obviously I'm doing something incorrectly, but the documentation provides no examples and my search-fu seems to indicate that either no one is trying this or anyone who is trying it isn't talking about it. Does anyone have suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我自己找到了问题的答案。 该问题是由编辑模型而不是
ModelItem
包装器引起的。 我应该做的(并且确实有效)是这样的:当我编写第一个代码时,我很困惑,不确定应该如何在 Children 属性上调用 Add() ; 它看起来像 ModelProperty.Value 用 ModelItemCollection 包装集合,所以除非你不遗余力地让你的类使用钝化接口,否则这应该可以工作。
I found the answer to my question myself. The problem is caused by editing the model instead of the
ModelItem
wrapper. What I should have done (and does work) is something like this:I was confused when I wrote the first code and unsure how I was supposed to call Add() on the Children property; it looks like ModelProperty.Value wraps collections with ModelItemCollection, so unless you go out of your way to make your class use an obtuse interface this should work.