如何实例化UserControl并在XAML中将项添加到其Container

时间:2014-08-28 14:46:05

标签: c# wpf xaml user-controls

我有以下UserControl:

<UserControl x:Class="UserControlTest.UserControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<StackPanel x:Name="MainPanel" Background="White">
    <TextBlock Text="BasePanel"/>
</StackPanel>

我的MainWindwo.XAML:

<Window x:Class="UserControlTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:UC="clr-namespace:UserControlTest"
    Title="MainWindow" Height="350" Width="525">
<DockPanel Name="dpMain">
    <UC:Control x:Name="ucBaseControl" />

</DockPanel>

在代码隐藏的MainWindow.xaml.cs中:

namespace UserControlTest
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            TextBox tbWorld = new TextBox();
            tbWorld.Text = "Hello World";
            ucBaseControl.MainPanel.Children.Add(tbWorld);
        }
    }
}

有没有办法在XAML中实现这一点以避免代码隐藏?

非常感谢你!

2 个答案:

答案 0 :(得分:1)

您可以尝试执行以下操作:

XAML:

<UserControl x:Class="WpfApplication1.BaseControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel x:Name="root">
        <TextBlock>I'm from base</TextBlock>
        <StackPanel x:Name="newPanel">

        </StackPanel>
    </StackPanel>
</UserControl>

代码背后:

using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;

namespace WpfApplication1
{
    [ContentProperty("NewControls")]
    public partial class BaseControl : UserControl
    {
        public UIElementCollection NewControls
        {
            get { return (UIElementCollection)GetValue(NewControlsProperty); }
            set { SetValue(NewControlsProperty, value); }
        }

        public static readonly DependencyProperty NewControlsProperty = DependencyProperty.Register("NewControls", typeof(UIElementCollection), typeof(BaseControl));

        public BaseControl()
        {
            InitializeComponent();

            this.NewControls = new UIElementCollection(this, this);

            this.Loaded += BaseControl_Loaded;
        }

        void BaseControl_Loaded(object sender, RoutedEventArgs e)
        {
            foreach (UIElement element in NewControls.Cast<UIElement>().ToList())
            {
                NewControls.Remove(element);

                this.newPanel.Children.Add(element);
            }
        }
    }
}

在另一个控件或窗口中:

xmlns:local="clr-namespace:WpfApplication1"
...
<local:BaseControl>
    <TextBlock>I'm from new</TextBlock>
</local:BaseControl>

不确定它是否完全符合您的需求,但可以作为一个良好的基础。

答案 1 :(得分:0)

这是我的解决方案。

我的UserControl:

<UserControl x:Class="ucFancyMenu" x:Name="MySelf"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Label Height="30" VerticalAlignment="Top" Background="#F0F">So Fancy</Label>
        <ItemsControl Margin="0 30 0 0" ItemsSource="{Binding ElementName=MySelf, Path=Items}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </Grid>
</UserControl>

UserControl类:

<Markup.ContentProperty("Items")> _
Public Class ucFancyMenu

    Public Property Items As New List(Of UIElement)

End Class

如何在其他Xamls中使用它:

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>

        <local:ucFancyMenu>
            <Button>FancyBtn 1</Button>
            <Button>FancyBtn 2</Button>
            <Button>FancyBtn 3</Button>
            <Button>FancyBtn 4</Button>
            <Button>FancyBtn 5</Button>
            <Button>FancyBtn 6</Button>
            <Button>FancyBtn 7</Button>
        </local:ucFancyMenu>

    </Grid>
</Window>