Как повторно использовать макеты в WPF - PullRequest
7 голосов
/ 09 июня 2010

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

Теперь каждая вкладка по сути будет иметь одинаковый макет, просто разные вещи в макете иЯ хотел иметь возможность повторно использовать один и тот же макет, чтобы мне не приходилось менять во многих местах (это просто не хорошее программирование).Могу ли я сделать это с помощью ресурсов или, возможно, стилей.

Пожалуйста, предоставьте пример светлого кода, если это возможно.

РЕДАКТИРОВАТЬ: Я решил добавить пример того, что я пытаюсь сделать, потому чтоЯ все еще не понимаю.

В каждом TabItem я пытаюсь воссоздать эту сетку (она немного сложнее, но вы поняли):

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="200"/>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Border Margin="10"
                            BorderBrush="{StaticResource MediumColorBrush}"
                            CornerRadius="10"
                            BorderThickness="2"
                            Grid.Row="0">

               <!-- First content goes here -->

        </Border>

        <Border Margin="10"
                            BorderBrush="{StaticResource MediumColorBrush}"
                            CornerRadius="10"
                            BorderThickness="2"
                            Grid.Row="1">

               <!-- Second content goes here -->

        </Border>

    </Grid>

, как вы можетеСмотрите также 2 границы одинаковы.Теперь мне нужно разместить заполнитель содержимого там, где находятся мои комментарии.Я не хочу объявлять этот макет Grid в словаре ресурсов, а затем, где я его использую, помещать отдельный контент в каждую рамку.

У меня может быть много TabItems, поэтому повторение этого кода не является хорошей идеей, и каждыйНа вкладке будет разный контент в двух заполнителях.

Я могу использовать вещь

<ContentPresenter Content="{Binding}" />

, но только для 1 контента, что произойдет, когда будет больше.

Ответы [ 2 ]

3 голосов
/ 10 июня 2010

TabItem - это ContentControl, который разрешает любое дочернее содержимое, но также позволяет создавать шаблоны содержимого, что именно то, что вы пытаетесь сделать.Вы можете использовать DataTemplate таким образом, чтобы сделать ваш общий макет.ContentPresenter является местозаполнителем для различного содержимого каждого TabItem.

<DataTemplate x:Key="ButtonViewerTemplate">
    <DockPanel>
        <Button DockPanel.Dock="Bottom" Content="OK"/>
        <Button DockPanel.Dock="Bottom" Content="Cancel"/>
        <Border Background="Aqua" BorderBrush="Red" BorderThickness="2" Padding="5">
            <ContentPresenter Content="{Binding}" />
        </Border>
    </DockPanel>
</DataTemplate>

Чтобы использовать шаблон, просто установите его для ContentTemplate каждого TabItem.Это работает со всем, что происходит от ContentControl.

<TabControl>
    <TabItem ContentTemplate="{StaticResource ButtonViewerTemplate}" Header="Some Buttons">
        <UniformGrid>
            <Button Content="XXXXX"/>
            <Button Content="XXXXX"/>
            <Button Content="XXXXX"/>
            <Button Content="XXXXX"/>
        </UniformGrid>
    </TabItem>
    <TabItem ContentTemplate="{StaticResource ButtonViewerTemplate}" Header="All Blue">
        <Border Background="Blue" MinHeight="50"/>
    </TabItem>
    <TabItem ContentTemplate="{StaticResource ButtonViewerTemplate}" Header="Image">
        <Image Source="http://i.msdn.microsoft.com/Platform/Controls/StoMastheadMSDN/resources/logo_msdn.png"/>
    </TabItem>
</TabControl>
2 голосов
/ 09 июня 2010

Ingo,

Код всегда доступен на MSDN.Проверьте это: UserControl , Пользовательские элементы управления , DataTemplates .

Вот несколько примеров каждого подхода.Для простоты, давайте предположим, что макет, который вы хотите скопировать, представляет собой одну строку текста с зеленым передним планом (на самом деле это может быть совсем другое, но вы поняли).


1,Пользовательский элемент управления

Xaml:

<UserControl x:Class="WpfApplication1.GreenTextUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <TextBlock x:Name="txt" Foreground="Green"/>
</UserControl>

C #:

using System.Windows.Controls;

namespace WpfApplication1
{
  public partial class GreenTextUserControl : UserControl
  {
    public string Text
    {
      get { return txt.Text;}
      set { txt.Text = value; }
    }

    public GreenTextUserControl()
    {
      InitializeComponent();
    }
  }
}

Управление вкладками:

<TabControl>
  <TabItem Header="Tab 1">
    <loc:GreenTextUserControl Text="This is Tab 1"/>
  </TabItem>
  <TabItem Header="Tab 2">
    <loc:GreenTextUserControl Text="This is Tab 2"/>
  </TabItem>
  <TabItem Header="Tab 3">
    <loc:GreenTextUserControl Text="This is Tab 3"/>
  </TabItem>
</TabControl>

2.Пользовательский элемент управления

C #:

  public class GreenTextBlock : TextBlock
  {
    public GreenTextBlock()
    {
      Foreground = Brushes.Green;
    }
  }

TabControl:

<TabControl>
  <TabItem Header="Tab 1">
    <loc:GreenTextBlock Text="This is Tab 1"/>
  </TabItem>
  <TabItem Header="Tab 2">
    <loc:GreenTextBlock Text="This is Tab 2"/>
  </TabItem>
  <TabItem Header="Tab 3">
    <loc:GreenTextBlock Text="This is Tab 3"/>
  </TabItem>
</TabControl>

Если ваш макет болееСложный, чем текстовый блок, пользовательские элементы управления также позволяют определить его в XAML, но он отличается от UserControls.


3.DataTemplate

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:System="clr-namespace:System;assembly=mscorlib" 
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
    <x:Array x:Key="GreenText" Type="{x:Type System:String}">
      <System:String>This is Tab 1</System:String>
      <System:String>This is Tab 2</System:String>
      <System:String>This is Tab 3</System:String>
    </x:Array>

    <!--Tab item content data template-->
    <DataTemplate x:Key="GreenTextTemplate">
      <TextBlock Text="{Binding}" Foreground="Green"/>
    </DataTemplate>
  </Window.Resources>
    <Grid>
    <TabControl ItemsSource="{StaticResource GreenText}">
      <TabControl.ItemContainerStyle>
        <Style TargetType="{x:Type TabItem}">
          <Setter Property="ContentTemplate" Value="{StaticResource GreenTextTemplate}"/>
        </Style>
      </TabControl.ItemContainerStyle>
    </TabControl>
  </Grid>
</Window>

Вот и все :).Надеюсь, это поможет.

...