Necesito crear un control de usuario personalizado para poder agregar fácilmente algún control para que todos los controles que implementan el control de usuario personalizado puedan verse afectados.

Esto es lo que hago

public class CustomUserControl : UserControl
    {
        public CustomUserControl()
        {
            var stack = new StackPanel();
            stack.Children.Add(new TextBox() { Width = 100, Height = 100 });
            Content = stack; // need to add extra control to content
            //AddChild("test"); // this also fail
            //AddChild(stack); // this result in hard error
        }
    }

En el xaml

<control:CustomUserControl x:Class="Sample"
             xmlns:control="clr-namespace:Sample.Controls;assembly=Sample"
             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">
    <Grid>
            <TextBox Width="100" Height="100"/>
    </Grid>
</control:CustomUserControl>

Quiero que muestre 2 cuadros de texto, pero solo muestra uno, tal vez porque el contenido anulado por el padre.

0
kirie 16 feb. 2015 a las 17:29

4 respuestas

La mejor respuesta

Pero si desea agregarlo desde el código, para darle un nombre a la cuadrícula, luego agregue los hijos del código. Por ejemplo, XAML:

<UserControl x:Class="WpfApplication1.UserControl1"
         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">
<Grid x:Name="MyGrid">
    <Grid.RowDefinitions>
        <RowDefinition Height="29*"/>
        <RowDefinition Height="271*"/>
    </Grid.RowDefinitions>
    <TextBlock Text="TextBox1 Text" Grid.Row="0"/>
</Grid>

Y el archivo .cs será:

public UserControl1()
    {
        InitializeComponent();
        var textBlock2 = new TextBlock();
        textBlock2.Text = "TextBox2 Text";
        MyGrid.Children.Add(textBlock2);
        Grid.SetRow(textBlock2,1);
    }
}
0
Vladislav 18 feb. 2015 a las 08:03

Después de excavar UserControl y el error de prueba, finalmente obtengo lo que quiero, simplemente anule el renderizado en el control del usuario

protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
        {
            if (_group == null) //private field, hack so it only adding content once
            {
                var grid = new StackPanel() { Orientation = Orientation.Vertical };
                _group = new WarningBoxControl();

                var content = Content as StackPanel;
                if (content != null)
                {
                    _group.DataContext = content.DataContext;
                    content.Children.Insert(0, _group);
                }
            }

            base.OnRender(drawingContext);
        }

El único problema con esto es Control que implementa CustomUserControl debe tener un panel de pila en su raíz. independientemente de que esto sea más fácil de mantener siempre que quiera poner un control adicional o algo así

0
kirie 18 feb. 2015 a las 05:12

Si desea un control de usuario personalizado con dos cuadros de texto, simplemente hágalo en el XAML del control: no es necesario que lo haga en el constructor.

En otras palabras, elimine su constructor:

public class CustomUserControl : UserControl
{
}

Y deshacerse de Grid en el XAML:

<control:CustomUserControl x:Class="Sample" ... >
    <StackPanel>
        <TextBox Width="100" Height="100"/>
        <TextBox Width="100" Height="100"/>
    </StackPanel>
</control:CustomUserControl>
0
Steven Rands 16 feb. 2015 a las 14:50

Su código de constructor se ejecuta después de la generación de XAML. Su contenido primero se establece en "Cuadrícula" en XAML, luego "Contenido = pila" en el archivo .cs. Debe establecer el nombre de su cuadrícula en xaml y usarlo en el archivo .cs. Pero no lo hagas, por favor, usa MVVM.

0
Vladislav 16 feb. 2015 a las 14:38