2010-06-09 27 views
6

Tôi đang cố gắng tạo một ứng dụng sẽ được gắn thẻ trong đó mỗi tab sẽ có vùng nút và vùng xem.Cách sử dụng lại bố trí trong WPF

Bây giờ, mỗi tab về cơ bản sẽ có bố cục giống nhau trong bố cục và tôi muốn có thể sử dụng lại bố cục tương tự để tôi không phải thay đổi ở nhiều nơi (nó chỉ là lập trình không tốt). Tôi có thể thực hiện điều này bằng cách sử dụng tài nguyên hoặc có thể là Kiểu.

Vui lòng cung cấp ví dụ về mã vạch nếu có thể.

EDIT: Tôi đã quyết định thêm ví dụ về những gì tôi đang cố gắng làm vì tôi vẫn chưa nhận được.

Dưới mỗi TabItem Tôi đang cố gắng để tái tạo lưới này (Đó là một chút phức tạp hơn nhưng bạn sẽ có được ý tưởng):

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

như bạn có thể xem thêm 2 biên giới đều giống nhau. Bây giờ tôi cần phải đặt một số giữ chỗ nội dung, nơi bình luận của tôi. Tôi không thể tuyên bố bố trí lưới này trong một từ điển tài nguyên và sau đó nơi tôi sử dụng nó đặt nội dung riêng biệt vào mỗi biên giới.

Tôi có thể có rất nhiều TabItem để lặp lại mã này không phải là ý tưởng hay và mỗi trang Tab sẽ có nội dung khác nhau trong 2 trình giữ chỗ.

Tôi có thể sử dụng điều

<ContentPresenter Content="{Binding}" /> 

nhưng chỉ trong vòng 1 nội dung, những gì sẽ xảy ra khi sẽ có nhiều hơn nữa.

Trả lời

1

Ingo,

Mã luôn có sẵn trên MSDN. Kiểm tra điều này: UserControl, Custom controls, DataTemplates.

Dưới đây là một số ví dụ về mỗi cách tiếp cận. Vì lợi ích của sự đơn giản, hãy giả sử bố cục bạn muốn sao chép là một dòng văn bản có nền trước màu xanh lá cây (trong thực tế nó có thể thực sự khác nhau, nhưng bạn có ý tưởng).


1. User Control

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(); 
    } 
    } 
} 

Tab kiểm soát:

<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.điều khiển tùy chỉnh

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> 

Nếu bố trí của bạn là phức tạp hơn TextBlock, điều khiển tùy chỉnh cũng cho phép bạn định nghĩa nó trong XAML nhưng nó khác với 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> 

Vậy là xong :). Hy vọng nó giúp.

+0

Cảm ơn bạn, vẫn gói đầu quanh WPF. Bây giờ, chỉ cần nhận ra khả năng tạo ra lớp của riêng tôi, những người thừa kế từ TabItem nhưng có cấu trúc sẵn sàng. Không chắc chắn mặc dù nếu điều này làm việc như tôi không biết làm thế nào để sau đó thêm mọi thứ vào bố trí. –

+0

Ok phát hiện ra rằng bạn không thể kế thừa các lớp Xaml vì vậy đó là không sử dụng cho tôi. Tất cả các bài viết bạn đã đề cập về việc tùy chỉnh các điều khiển không sử dụng lại bố cục và nếu bạn muốn tôi có thể tùy chỉnh TabItem hoặc thứ gì đó để thực hiện công việc này, tôi không nhìn thấy nó. –

+0

Tùy chỉnh TabItem dường như không phù hợp với tôi (mặc dù bạn có thể thông qua Điều khiển tùy chỉnh). Thay vào đó bạn có thể tạo một điều khiển người dùng và đặt nó bên trong mỗi TabItem. Thêm giải pháp thanh lịch là tạo DataTemplate và sử dụng nó như ItemTemplate cho TabControl ... – Anvaka

3

TabItem là một ContentControl cho phép bất kỳ nội dung con nào, mà còn cho phép tạo khuôn mẫu nội dung, đó chính xác là những gì bạn đang cố gắng làm. Bạn có thể sử dụng DataTemplate như thế này để thực hiện bố cục được chia sẻ của mình. ContentPresenter là trình giữ chỗ cho nội dung khác nhau của mỗi 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> 

Để sử dụng mẫu, chỉ cần đặt mẫu vào mỗi ContentTemplate của TabItem. Điều này làm việc với bất cứ điều gì bắt nguồn từ 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> 
+0

OK giả sử tôi có một lưới bên trong TabItem, tôi sẽ định nghĩa lưới bên trong DataTemplate. Nhưng nếu tôi không thể thêm nội dung vào lưới khác nhau giữa các tab. Có lẽ tôi nên định nghĩa một kiểu lưới và sử dụng nó trên mỗi lưới nhưng tôi không chắc chắn cách xác định kích thước hàng và cột theo kiểu lưới. –

+0

Cả DataTemplate và TabItem Content đều có thể chứa bất cứ thứ gì, bao gồm cả Panels như Grid. Bất cứ điều gì cần phải khác nhau giữa các mặt hàng templated chỉ có thể được đặt trong nội dung TabItem. –

+0

Ok bạn có nghĩa là các UniformGrid bạn tạo ra trong codeWindow thứ hai sẽ được đưa vào ranh giới màu Aqua tha trong cửa sổ đầu tiên thay thế các nội dung/ràng buộc chàng? –

Các vấn đề liên quan