Читаю Роберта Мартина и пытаюсь постичь все тонкости рефакторинга.
Если с C#
-кодом все более-менее понятно и код мало-помалу начинает радовать глаз, то с XAML
всё печально. Разметка громоздкая и трудночитаемая.
Понятно, что многое связано с xml-"наследственностью". Xml избыточен и не очень приятен для глаз, но всё же. Какие есть способы и кто что применяет для рефакторинга xaml?
В идеале хотелось бы избавиться от десятиуровневой иерархии и получить короткие "методы" по 5-7 строчек (как это у меня сделано в c#-коде).
Привожу разметку одного из окон моего последнего WPF-приложения (все 320 строчек "фарша"):
<Window x:Class="InfoReceiverB.Views.EditorWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:InfoReceiverB.Views"
mc:Ignorable="d"
Title="Менеджер скриптов" Icon="/papers2.ico"
WindowStartupLocation="CenterScreen"
Height="700" Width="1100">
<Grid Margin="3">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ListBox Padding="2.5" Margin="3"
ItemsSource="{Binding Repo.Queries}"
SelectedItem="{Binding SelectedQuery}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id}" Margin="0,0,2,0"/>
<TextBlock Text="{Binding Caption}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Grid.Column="1"
Margin="0,3,3,3">
<Button Content="+"
Padding="5" Margin="0,0,0,3"
Command="{Binding AddQueryCommand}"/>
<Button Content="-"
Padding="5" Margin="0,0,0,3"
Command="{Binding DelQueryCommand}"
CommandParameter="{Binding SelectedQuery}">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="CommandParameter" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackPanel>
</Grid>
<GridSplitter Grid.Row="1" Height="3"
HorizontalAlignment="Stretch"
Background="DarkGray" Margin="3,0"/>
<Grid Grid.Row="2" DataContext="{Binding SelectedQuery}">
<Grid.Style>
<Style TargetType="Grid">
<Style.Triggers>
<Trigger Property="DataContext" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False"/>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Style>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Id}"
Padding="5" Margin="3,3,0,3"/>
<TextBox Grid.Column="1"
Text="{Binding Caption}"
Padding="5" Margin="0,3,3,3"
AcceptsReturn="True"/>
<TextBox Grid.Row="1" Grid.ColumnSpan="2"
Text="{Binding Body}"
FontFamily="Consolas" FontSize="14"
Padding="5" Margin="3,0,3,3"
AcceptsReturn="True" AcceptsTab="True"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"/>
</Grid>
</Grid>
<GridSplitter Grid.Column="1" Width="3"
HorizontalAlignment="Stretch"
Background="DarkGray" Margin="0,3"/>
<Grid Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ListBox Padding="2.5" Margin="3"
ItemsSource="{Binding Repo.QueryPacks}"
SelectedItem="{Binding SelectedQueryPack}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id}" Margin="0,0,2,0"/>
<TextBlock Text="{Binding Caption}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Grid.Column="1"
Margin="0,3,3,3">
<Button Content="+"
Padding="5" Margin="0,0,0,3"
Command="{Binding AddQueryPackCommand}"/>
<Button Content="-"
Padding="5" Margin="0,0,0,3"
Command="{Binding DelQueryPackCommand}"
CommandParameter="{Binding SelectedQueryPack}">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="CommandParameter" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackPanel>
</Grid>
<GridSplitter Grid.Row="1" Height="3"
HorizontalAlignment="Stretch"
Background="DarkGray" Margin="3,0"/>
<Grid Grid.Row="2" DataContext="{Binding SelectedQueryPack}">
<Grid.Style>
<Style TargetType="Grid">
<Style.Triggers>
<Trigger Property="DataContext" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False"/>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Style>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Id}"
Padding="5" Margin="3,3,0,3"/>
<TextBox Grid.Column="1"
Text="{Binding Caption}"
Padding="5" Margin="0,3,3,3"/>
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListBox Name="list1" Padding="2.5" Margin="3"
ItemsSource="{Binding DataContext.Repo.Queries,
RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id}" Margin="0,0,2,0"/>
<TextBlock Text="{Binding Caption}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Grid.Column="1"
Margin="0,3" VerticalAlignment="Center">
<Button Content=">"
Padding="5" Margin="0,0,0,3"
Command="{Binding DataContext.AddQueryToPackCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
CommandParameter="{Binding SelectedItem, ElementName=list1}">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="CommandParameter" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button Content="<"
Padding="5" Margin="0,7,0,3"
Command="{Binding DataContext.DelQueryFromPackCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
CommandParameter="{Binding SelectedItem, ElementName=list2}">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="CommandParameter" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button Content="^"
Padding="5" Margin="0,0,0,3"
Command="{Binding DataContext.UpQueryInPackCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
CommandParameter="{Binding SelectedItem, ElementName=list2}">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="CommandParameter" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button Content="v"
Padding="5" Margin="0,0,0,3"
Command="{Binding DataContext.DownQueryInPackCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
CommandParameter="{Binding SelectedItem, ElementName=list2}">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="CommandParameter" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackPanel>
<ListBox Grid.Column="2" Name="list2"
Padding="2.5" Margin="3"
ItemsSource="{Binding Queries}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id}" Margin="0,0,2,0"/>
<TextBlock Text="{Binding Caption}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
</Grid>
</Grid>
<UniformGrid Grid.Row="1" HorizontalAlignment="Right"
Rows="1">
<Button Grid.Column="1"
Content="Применить" IsDefault="True"
Padding="5" Margin="0,3,3,3"
Command="{Binding ApplyCommand}"
Click="ApplyButtonClick"/>
<Button Grid.Column="2"
Content="Отмена" IsCancel="True"
Padding="5" Margin="0,3,3,3"/>
</UniformGrid>
</Grid>
</Window>
Буду рад любым рекомендациям и замечаниям, особенно с примерами
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Возникла такая проблема: код запускается, но не считывает текстовый файл, тем более не создает новыйПодскажите как можно изменить
Имеется проект EF6 (code-First)В сущности File имеется свойство FullPath, содержащее полный путь к файлу в верхнем регистре