Controls inside a custom control cannot move
I have a custom control (say MyContainer) that is just a ScrollViewer with an inner canvas.
I can add controls to MyContainer as they would to Canvas, but in XAML design, those controls do not move like they would in a regular Canvas; they cannot be moved with the mouse.
Here's the MyContainer code:
[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)
{
;
}
}
Where am I going wrong?
PS: please avoid responses like "don't use editor, only use XAML"; I need to make User Control available through a GUI.
source to share
I think you have not chosen the correct base class. There are certain points of extensibility in WPF that you must use for certain types of UI elements, and I am assuming the constructor is hardcoded into those classes.
Different types of interface elements:
- Visuals: These are usually derived from
FrameworkElement
, and their purpose is to display something that the user would normally not interact with (like a text block). - Controls: These are what the user can interact with, such as buttons, checkboxes, text boxes, scrolls, etc. They usually come from
Control
orContentControl
. - Panels: Their purpose is to lay out other interface elements,
Grid
orStackPanel
are examples. They all come from the base classPanel
. - Controls: These usually provide selections for multiple items.
ListBox
,ComboBox
andTreeView
are examples for them. They all come fromItemsControl
.
Another important thing: ContentControl
u ItemsControl
can display any object, not just those that can display themselves. They use the WPF data templating mechanism for this (by default, it is called ToString
on a non-rendered object and the resulting string is placed in TextBlock
).
As per your code, I would assume that you either want to implement a panel or a control. For panels, you should be aware of WPF 's Measure - Arrange - Render loop and how you can use it to arrange the children of a panel.
Implementing an item control is a bit tricky because essentially the item control uses items that wrap the actual content of each displayable (e.g. ListBoxItem
), a panel to lay out those items, an item container generator to dynamically create children, and of course you you can use styles and templates. Most item controls also include a scroll viewer. If you want to know more about item controls, I highly recommend you read the blog section Item Controls: A to Z by Dr. WPF.
I haven't tried it, but I'm pretty sure that if you choose the correct base class to extend then you can use your control correctly with the designer.
source to share