简体   繁体   中英

WPF replace UIElement with another

If I have

<StackPanel>
    <Button name="btn"/>
</StackPanel>

how could I replace Button btn for a different control when I press that button? In this case I know the parent is a StackPanel so I could cast the parent to a stackPanel and then replace that child. but what if I have a Border?

<Border>
    <Button name="btn"/>
</Border>

Thanks to McGarnagle I created this extension method

how can I replace a Button with my custom control without knowing in advance the parent of the button?

Edit

    public static void ReplaceWith(this FrameworkElement elementToReplace, FrameworkElement newControl)
    {
        newControl.Width = elementToReplace.Width;
        newControl.Height = elementToReplace.Height;
        newControl.Margin = elementToReplace.Margin;

        // get parent of control
        var parent = elementToReplace.Parent;

        if (parent is Panel)
        {
            var panel = (Panel)parent;

            for (var i = 0; i < panel.Children.Count; i++)
            {
                if (panel.Children[i] == elementToReplace)
                {
                    panel.Children.RemoveAt(i);
                    panel.Children.Insert(i, newControl);
                    break;
                }
            }
        }
        else if (parent is Decorator)
        {
            ((Decorator)parent).Child = newControl;
        }
        else if (parent is ContentControl)
        {
            ((ContentControl)parent).Content = newControl;
        }
        else
        {
            if(Debugger.IsAttached)
                Debugger.Break();

            throw new NotImplementedException("Missing other possibilities to implement");
        }
    }

I suppose you could cycle through the possible base classes. There aren't that many: StackPanel is a Panel , Border is a Decorator , …

var parent = btn.Parent;
var replacement = new TextBlock { Text = "replacement" };
if (parent is Panel)
{ 
    var panel = (Panel)parent;
    panel.Children.Remove(btn);
    panel.Children.Add(replacement);
}
else if (parent is Decorator)
{ 
    ((Decorator)parent).Child = replacement;
}
else if (parent is ContentControl)
{
    ((ContentControl)parent).Content = replacement;
}

Yo can get the logical parent of Control and check it's type using the operator is like this:

var parent = MyButton.Parent;

if (parent is StackPanel)
{ 
    // do something with StackPanel
}

if (parent is Border) 
{
    // do something with Border
}

All containers are Panel or ContentControl or UserControl. So you can check if parent is inherited from one of these controls.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM