Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Controls inside custom control aren't movable

I have a custom control (let's say MyContainer) that simply is a ScrollViewer with a Canvas inside.

I'm able to add controls to MyContainer like in a Canvas but in XAML designer this controls aren't movable like in a normal Canvas; they can't 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 wrong?

PS: please avoid replies like "don't use editor, use XAML code only"; I need to make a User Control usable via graphic interface.

like image 675
rPulvi Avatar asked Sep 07 '26 19:09

rPulvi


1 Answers

I think that you did not choose the correct base class. In WPF there are certain extensibility points that you should use for certain types of UI elements and I guess that the designer is hard-wired to these classes.

The different types of UI Elements are:

  1. Visuals: they usually derive from FrameworkElement and their purpose is to display something that the user normally does not interact with (e.g. a text block).
  2. Controls: they represent something that the user can interact with, like buttons, check boxes, text boxes, scroll viewers, etc. They usually derive from Control or ContentControl.
  3. Panels: their purpose is to layout other UI Elements, Grid or StackPanel are examples. They all derive from the Panel base class.
  4. Items controls: they usually provide selection for a number of items. ListBox, ComboBox, and TreeView are examples for them. All of them derive from ItemsControl.

Another important thing is that ContentControls and ItemsControls can display any object, not only those that can render themselves. They use the WPF Data Templating mechanism for that (the default is calling ToString on a non-renderable object and putting the resulting string in a TextBlock).

According to your code, I would assume that you either want to implement a panel or an items control. For panels, you should know about the Measure - Arrange - Render cycle of WPF and how you can use it to layout the panel's children.

Implementing an items control is a little bit harder because essentially an items control uses items that wrap the actual content of each displayed object (e.g. ListBoxItem), a panel to layout these items, an items container generator to dynamically create the child items, and of course you can use styles and templates. Most of the items controls also incorporate a scroll viewer. If you want to learn more about items controls, I strongly encourage you to read the "Items Controls: A to Z" blog series by Dr. WPF.

I haven't tried it out but I'm sure if you choose the correct base class to extend from, then you can use your control with the designer properly.

like image 182
feO2x Avatar answered Sep 10 '26 10:09

feO2x



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!