2012-05-03 16 views
44

Sto provando a creare un controllo utente che ha un Grid con due righe. la prima riga per un titolo e la seconda per un contenuto che verrà definito all'esterno del controllo utente, ad esempio Button nel nostro esempio.WPF - Hosting del contenuto all'interno di un UserControl

In qualche modo non l'ho fatto funzionare.

UserControl1 XAML:

<Grid Background="LightBlue"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="50" /> 
     <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 
    <TextBlock Text="Title" FontSize="30" Margin="10,0,0,0"/> 
</Grid> 

MainWindow XAML:

<Grid> 
    <local:UserControl1> 
     <Button>Click me</Button> 
    </local:UserControl1> 
</Grid> 

L'immagine qui sotto dovrebbe spiegare qual è il mio problema: enter image description here

risposta

53

Il seguente codice

<local:UserControl1> 
    <Button>Click me</Button> 
</local:UserControl1> 

Significa che si imposta la proprietà Contenuto di UserControl1 come pulsante. Questo pulsante sostituisce semplicemente il markup UserControls1. Quindi tutte le cose che hai in UserControl1.xaml non ci sono più.

EDIT

Se si desidera che l'UserControl per ospitare un certo margine di profitto che sarà fissato da qualche parte al di fuori di esso, è possibile aggiungere un DependencyProperty ad esso, per esempio:

/// <summary> 
    /// Gets or sets additional content for the UserControl 
    /// </summary> 
    public object AdditionalContent 
    { 
     get { return (object)GetValue(AdditionalContentProperty); } 
     set { SetValue(AdditionalContentProperty, value); } 
    } 
    public static readonly DependencyProperty AdditionalContentProperty = 
     DependencyProperty.Register("AdditionalContent", typeof(object), typeof(CalibrationPoint), 
      new PropertyMetadata(null)); 

e aggiungere un po elemento al suo markup per ospitare quel contenuto aggiuntivo. Ecco un esempio estendendo il markup che hai fornito:

<UserControl ... Name="userControl"> 
    <Grid Background="LightBlue"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="50" /> 
      <RowDefinition Height="*" /> 
     </Grid.RowDefinitions> 

     <TextBlock Text="Title" FontSize="30" Margin="10,0,0,0"/> 
     <ContentPresenter Content="{Binding AdditionalContent, ElementName=userControl}" /> 
    </Grid> 
</UserControl> 

Ora è possibile utilizzarlo come segue:

<local:UserControl1> 
    <local:UserControl1.AdditionalContent> 
     <Button>Click me</Button> 
    </local:UserControl1.AdditionalContent> 
</local:UserControl1> 
+1

Perché utilizzare una proprietà di dipendenza aggiuntiva e non solo sostituire il modello di controllo e associarlo alla proprietà content? – codekaizen

+0

Sono d'accordo con te. Ho visto la tua risposta subito dopo aver pubblicato la mia. Sono stato io a votare i tuoi – EvAlex

+0

La spiegazione del perché non funziona è grandiosa, ma ho trovato la risposta di @ blindmeis come più utile. – TarkaDaal

21

È necessario impostare la ControlTemplate:

<UserControl> 
<UserControl.Resources> 
    <Style TargetType="{x:Type local:UserControl1}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type local:UserControl1}"> 
        <Grid Background="LightBlue"> 
         <Grid.RowDefinitions> 
          <RowDefinition Height="50" /> 
          <RowDefinition Height="*" /> 
         </Grid.RowDefinitions> 
         <TextBlock Grid.Row="0" Text="Title" FontSize="30" Margin="10,0,0,0"/> 
         <ContentPresenter Grid.Row="1" /> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</UserControl.Resources> 
</UserControl> 
+8

C'è un motivo per cui lo si imposta tramite 'UserControl.Resources/Style' invece di inserire il' ControlTemplate' come contenuto di 'UserControl.Template'? – LWChris

+1

Sfortunatamente, sembra che l'impostazione della proprietà 'Template' di un' UserControl' non sia supportata: https://social.msdn.microsoft.com/forums/silverlight/en-US/a41ff344-1760-4e2d-afc2- 67307372b584/how-can-set-usercontrols-template-in-xaml –

+0

UserControl.Template funziona per me. Io uso TargetType = "{x: Type UserControl}". –

3

È possibile template l'utente controllo per aggiungere elementi visivi aggiuntivi come lo TextBlock.

<UserControl> 
<UserControl.Style> 
    <Style TargetType="{x:Type UserControl}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
     <ControlTemplate>    
      <Grid Background="LightBlue"> 
      <Grid.RowDefinitions> 
      <RowDefinition Height="50" /> 
      <RowDefinition Height="*" /> 
      </Grid.RowDefinitions> 
      <TextBlock Text="Title" FontSize="30" Margin="10,0,0,0"/> 
      <ContentPresenter Grid.Row="1" Content="{TemplateBinding Content}" /> 
      </Grid> 
     </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
    </Style> 
</UserControl.Style> 
<Button> 
    Click me! 
</Button> 
</UserControl> 
7

Usa modello con

< ContentControl />

Invece di utilizzare Content Presenter

Quindi collocare questo:

<UserControl.Style> 
     <Style TargetType="{x:Type UserControl}"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type UserControl}" > 
          <Grid Background="LightBlue"> 
          <Grid.RowDefinitions> 
          <RowDefinition Height="50" /> 
          <RowDefinition Height="*" /> 
          </Grid.RowDefinitions> 
          <TextBlock Text="Title" FontSize="30" Margin="10,0,0,0"/> 

         <ContentControl Grid.Row="1" Content="{TemplateBinding Content}" /> 

         </Grid> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </UserControl.Style> 

al tuo userControl

+0

* Usa template con ContentControl invece di usare ContentPresenter * - Perché? – Crono

+0

Meglio utilizzare ContentPresenter all'interno dei modelli, vedere http://stackoverflow.com/a/1288353/991267 –

Problemi correlati