У меня есть окно с управлением вкладкой и числом страниц - объекты вкладки. Каждый объект вкладки имеет то же расположение сетки - 6 строк и 4 столбца. Теперь, каждый объект вкладки содержит сетку со строкой и определениями столбца, поэтому почти половина XAML является определением сеток.
Как я могу определить эту сетку в одном месте и повторном использовании что определение в моем приложении? Шаблон? Пользовательский элемент управления?
Кроме того, 6x4, у меня есть еще только два размера сетки, которые повторяются: 8x4 и 6x6.
Править:
Забыл упоминать: средства управления в сетке отличаются для каждой вкладки. Я просто хочу определить сетку однажды в некотором ресурсе так, чтобы я мог снова использовать их на различных вкладках. Теперь XAML похож на это:
<TabControl>
<TabItem Header="Property">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!-- some controls here -->
</Grid>
</TabItem>
<TabItem Header="Style">
<Grid >
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!-- some controls here -->
</Grid>
</TabItem>
... and this repeats for several more tab items
</TabControl>
Это определение сетки повторяется для каждого объекта вкладки на форме. Меня раздражает, что половина XAML является определением сетки.
Существует ли способ определить эту сетку в одном месте и затем повторном использовании то определение?
Обычно можно написать DataTemplate для данных, которые попадают во вкладки. Этот DataTemplate будет содержать Grid.
Лучшим способом, на мой взгляд, будет использование ItemsControl
с ItemsPanelTemplate
, поскольку вам нужен контейнер для нескольких элементов:
<FrameworkElement.Resources>
<Style x:Key="GridItemsStyle"
TargetType="ItemsControl">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
</FrameworkElement.Resources>
<TabControl>
<TabItem>
<ItemsControl Style="{StaticResource GridItemsStyle}">
<TextBlock Grid.Row="1" Text="R1" />
<TextBlock Grid.Column="1"
Text="C1" />
</ItemsControl>
</TabItem>
<TabItem>
<ItemsControl Style="{StaticResource GridItemsStyle}">
<TextBlock Grid.Row="2"
Text="R2" />
<TextBlock Grid.Column="2"
Text="C2" />
</ItemsControl>
</TabItem>
</TabControl>
Как я могу определить эту сетку в одном месте и повторно использовать это определение в моем приложении? Шаблон? Пользовательский элемент управления?
На вашем месте я бы создал UserControl
или пользовательский Control
с повторяющимся кодом, а затем просто использовал бы этот элемент управления из текущего кода.
Другой подход заключается в использовании DataTemplate
или ControlTemplate
.
Создание ControlTemplate
для TabItem
ов также отлично подойдет.
У меня было что-то похожее. вопрос в том, как не помещать данные в сетки?
Поскольку вы снова и снова используете один и тот же макет, я думаю, вы помещаете похожие вещи в каждую ячейку.
Я создал собственный ItemsControl для каждой вкладки, чтобы поместить в нее данные, а затем создал стиль для ItemsControl, который отображал сетку.
<Style x:Key="GridItemsStyle"
TargetType="ItemsControl">
<Setter Property="ItemsPanel">
<Setter.Value>
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ContentPresenter Content="{Binding ElementName=Cell00}" Grid.Row="0" Grid.Column="0" />
<ContentPresenter Content="{Binding ElementName=Cell01}" Grid.Row="0" Grid.Column="1" />
<ContentPresenter Content="{Binding ElementName=Cell10}" Grid.Row="1" Grid.Column="0" />
<!-- ...And so on -->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
и в окне
<TabControl>
<TabItem>
<local:tab1 Style="{StaticResource GridItemsStyle}" />
</TabItem>
<TabItem>
<local:tab2 Style="{StaticResource GridItemsStyle}" />
</TabItem>
каждый CustomControl, унаследованный от ItemsControl
<ItemsControl x:Class="your_app.tab1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:your_app">
<ContentControl x:Name="Cell00">
<!-- Some stuff here -->
</ContentControl>
<ContentControl x:Name="Cell01">
<!-- Some stuff here -->
</ContentControl>
<ContentControl x:Name="Cell10">
<!-- Some stuff here -->
</ContentControl>
Это очень похоже на то, что делает Aelij, за исключением того, что я установил ContentPresenter, привязал его к имени и поместил itemsControl в его собственный объект (вы можете смешайте оба раствора).
Это все еще много кода, но я бы сказал, что вы все время сохраняете себе все определения строк и столбцов, и вам также нужно изменить сетку только в одном месте, если вам нужно несколько изменить ее.
Или вы можете просто унаследовать от сетки ...
using System.Windows.Controls;
public class AlreadySetupGrid:Grid
{
public AlreadySetupGrid()
{
for (int i = 0; i < 4; i++)
{
ColumnDefinitions.Add(new ColumnDefinition());
}
for (int i = 0; i < 6; i++)
{
RowDefinitions.Add(new RowDefinition());
}
}
}
А затем использовать это вместо вашей обычной сетки.