我有一个自定义控件(让我们说MyContainer),它只是一个内置Canvas的ScrollViewer。
我可以像在Canvas中一样向MyContainer添加控件,但在XAML设计器中,这个控件不像普通的Canvas那样可以移动;它们不能用鼠标移动。
这是MyContainer代码:
[ContentProperty("Children")]
public class MyContainer : ScrollViewer, IAddChild
{
private Canvas _innerCanvas;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public UIElementCollection Children
{
get { return _innerCanvas.Children; }
}
public MyContainer()
{
this._innerCanvas = new Canvas();
this.Content = _innerCanvas;
this.Loaded += MyContainer_Loaded;
}
void MyContainer_Loaded(object sender, RoutedEventArgs e)
{
_innerCanvas.Height = this.ActualHeight;
_innerCanvas.Width = this.ActualWidth;
}
void IAddChild.AddChild(object value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
UIElement uie = value as UIElement;
if (uie == null)
{
throw new ArgumentNullException("value");
}
_innerCanvas.Children.Add(value as UIElement);
}
void IAddChild.AddText(string text)
{
;
}
}
我哪里错了?
PS:请避免回复,例如"不要使用编辑器,只使用XAML代码&#34 ;;我需要通过图形界面使用户控件可用。
答案 0 :(得分:2)
我认为你没有选择正确的基类。在WPF中,某些可扩展性点应该用于某些类型的UI元素,我想设计师很难连接到这些类。
不同类型的UI元素是:
FrameworkElement
,其目的是显示用户通常不与之交互的内容(例如文本块)。Control
或ContentControl
。Grid
或StackPanel
是示例。它们都来自Panel
基类。ListBox
,ComboBox
和TreeView
就是他们的榜样。所有这些都来自ItemsControl
。另一个重要的事情是ContentControl
和ItemsControl
可以显示任何对象,而不仅仅是可以自我呈现的对象。他们使用WPF数据模板机制(默认是在不可渲染的对象上调用ToString
并将结果字符串放在TextBlock
)。
根据您的代码,我会假设您要么实现面板或项目控件。对于面板,您应该了解Measure - Arrange - Render cycle of WPF以及如何使用它来布置面板的子项。
实现项目控件有点困难,因为本质上一个项目控件使用包装每个显示对象的实际内容的项目(例如ListBoxItem
),一个面板来布局这些项目,一个项目容器生成器动态创建子项,当然您可以使用样式和模板。大多数项目控件还包含滚动查看器。如果您想了解有关项目控件的更多信息,我强烈建议您阅读WPF博士的"Items Controls: A to Z"博客系列。
我还没有尝试过,但我确定如果你选择正确的基类来扩展,那么你可以正确地使用你的控件与设计师。