Вопрос по wpf – WPF - хостинг контента внутри UserControl

49

Я пытаюсь создать пользовательский элемент управления, который имеетGrid с двумя рядами. первая строка для заголовка и вторая для контента, который будет определен вне пользовательского элемента управления, такого какButton в нашем примере.

Каким-то образом я не смог заставить его работать.

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>

Картинка ниже должна объяснить, в чем заключается моя проблема: enter image description here

Ваш Ответ

4   ответа
23

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>
UserControl.Template работает для меня. Я использую TargetType = & quot; {x: Type UserControl} & quot ;.
Спасибо тебе за это.
Установка шаблона элемента управления запрещает использование x: Name в любом контенте, который вы устанавливаете. Протестировано в .Net 4.7 wpf приложении. Namescope уже установлен, по-видимому.
Есть ли причина, по которой вы устанавливаете это черезUserControl.Resources/Style вместо того, чтобы просто положитьControlTemplate как содержаниеUserControl.Template?
К сожалению, похоже, что установкаTemplate свойствоUserControl не поддерживается:social.msdn.microsoft.com/forums/silverlight/en-US/…
59

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

Означает, что вы установилиUserControl1свойство Content для этой кнопки. Эта кнопка просто заменяетUserControls1разметка. Таким образом, все, что у вас есть в UserControl1.xaml, больше не существует.

EDIT

Если вы хотите, чтобы ваш UserControl содержал некоторую разметку, которая будет установлена где-то за ее пределами, вы можете добавитьDependencyProperty к нему, например:

    /// <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));

И добавьте некоторый элемент в его разметку, чтобы разместить этот дополнительный контент. Вот пример расширения разметки, которую вы предоставили:

<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>

Теперь вы можете использовать его следующим образом:

<local:UserControl1>
    <local:UserControl1.AdditionalContent>
        <Button>Click me</Button>
    </local:UserControl1.AdditionalContent>
</local:UserControl1>
Зачем использовать дополнительное свойство зависимостей, а не просто заменить шаблон управления и привязать его к свойству содержимого?
Объяснение того, почему это не работает, великолепно, но я нашел ответ @ blindmeis более полезным.
Вместо того, чтобы использовать<local:UserControl1.AdditionalContent> Вы можете просто использовать[ContentProperty("AdditionalContent")] атрибута в классе, и тогда возможно иметь собственные элементы управления непосредственно внутри содержимого элемента управления. Это здорово, потому что никто не может уничтожить его, случайно установив содержимое вместоAdditionalContent.
Что такоеCalibrationPoint? Интеллект не может найти возможное разрешение для этого класса, это что-то нестандартное? [[EDIT]] извините, я не проверял методRegister параметры. Я думаю, что это должно быть изменено наUserControl1 Скомпилировать.
Я с тобой согласен. Я увидел ваш ответ сразу после того, как опубликовал свой. Это я голосовал за тебя
8

< ContentControl />

Вместо использования Content Presenter

Так что разместите это:

<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>

в ваш пользовательский контроль

Лучше использовать ContentPresenter внутри шаблонов, см.stackoverflow.com/a/1288353/991267
Use template with ContentControl instead of using ContentPresenter - Why? – Crono Apr 1 '16 at 12:28
5

чтобы добавить дополнительные визуальные элементы, такие как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>
использование<ControlTemplate TargetType="{x:Type UserControl}"> заставить его работать в словаре ресурсов

Похожие вопросы