我写了一个自定义面板,显示其子项垂直或水平停靠,通过在两者之间移动分割器分开。由于Grid面板提供了大量开箱即用的功能,我只是继承了它。
要创建布局,在激活Loaded后,我会执行以下操作:
1) Read how many children it has and create the appropiate number of rows/colums.
2) Position every existing children in the corresponding row/colum.
3) Create, position and add a GridSplitter for every child.
这种方法看起来很好,但却为很多问题打开了大门:
因为它为每个孩子添加了一个GridSplitter,所以预期孩子的数量是两倍。如果有人添加了3个元素,则Children.Count将返回6。
用户可以在错误的位置插入/删除内容。
当此Grid用作ItemsControl的ItemsPanel时,它会抛出一个异常,因为在这种情况下,WPF(不是Silverlight)不允许直接操纵子进程。
这3个案例是我已经测试过的案例,但我很确定会出现更多情况,具体取决于用户使用它的方式。
事实证明,这个类必须被视为“实现细节”,所以真正的问题是,我应该在用户面前放置什么控件?
听起来它应该是一个Panel,但是我无法控制Children属性,因为它不是虚拟的,而且还有ItemsControl,我认为它可能是一个很好的候选者,但我真的不知道。
我非常感谢任何建议或方向以正确的方式做到这一点。
提前致谢。
答案 0 :(得分:1)
您会看到只使用网格,您只需要添加项目的必要方法。如在 myCustomGrid1.AddMyItem(***),Grids根本就没有ItemsSource属性。 ItemsControls会这样做 - 所以如果你需要支持声明项目来源,即myControl.ItemsSource = {Binding ...},你将从ItemsControl 派生你的控件。这不是一个双线 - 使你的ItemsPanel儿童可写是一个很大的挑战 - 没有简单的方法这样做。
这一切都是关于Grid设计中忽略的一件小事 - 不应该将分割器添加到Children集合中,因为Children是BO的可视化,而spliiters只是格式化元素。
这就是我要做的事。
忘掉ItemsSource&完全没有项目 - 这不是麻烦。向控件添加/删除项目的唯一方法是AddResiazableItem / RemoveResizbleItem。调用将添加项目和拆分器(对于中间项目),根据其方向扩展网格的行/列数,为可视子项设置Grid.Row / Grid.Column附加属性。您可以在内部保留实际对象以支持方向更改。
如果在任何阶段你想要将你的控件绑定到IEnumerable源 - 只需创建一个附加行为,它将遍历这些项并在循环中调用AddResiazableItem。
干杯。
P.S。对于主持人 - 编辑似乎变得破碎,小伙子们。我看不到第二项。 P.S.S.经过几次尝试后修复了它。