From wpf-dev-pack
Converts long inline XAML bindings to Property Element Syntax for better readability. Use when expressions exceed 100 characters, include nested RelativeSource, MultiBinding, or validation rules.
npx claudepluginhub christian289/dotnet-with-claudecode --plugin wpf-dev-packThis skill uses the workspace's default tool permissions.
Convert long inline bindings to structured Property Element Syntax for improved readability.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Convert long inline bindings to structured Property Element Syntax for improved readability.
Inline binding expressions can become horizontally extended and difficult to read:
<!-- Hard to read: 120+ characters in one line -->
<CheckBox IsChecked="{Binding Path=DataContext.IsAllChecked, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType=DataGrid, Mode=FindAncestor}}"/>
Split into Property Element Syntax:
<!-- Readable: Structured and maintainable -->
<CheckBox>
<CheckBox.IsChecked>
<Binding Path="DataContext.IsAllChecked"
UpdateSourceTrigger="PropertyChanged">
<Binding.RelativeSource>
<RelativeSource AncestorType="{x:Type DataGrid}"
Mode="FindAncestor"/>
</Binding.RelativeSource>
</Binding>
</CheckBox.IsChecked>
</CheckBox>
| Condition | Use Property Element Syntax |
|---|---|
| Line > 100 characters | Yes |
| Nested RelativeSource | Yes |
| MultiBinding | Yes |
| Multiple BindingValidationRules | Yes |
| Simple binding | No (keep inline) |
Inline (avoid):
<TextBlock Text="{Binding DataContext.Title, RelativeSource={RelativeSource AncestorType=Window}}"/>
Property Element (preferred):
<TextBlock>
<TextBlock.Text>
<Binding Path="DataContext.Title">
<Binding.RelativeSource>
<RelativeSource AncestorType="{x:Type Window}"/>
</Binding.RelativeSource>
</Binding>
</TextBlock.Text>
</TextBlock>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{local:FullNameConverter}">
<Binding Path="FirstName"/>
<Binding Path="LastName"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<TextBox>
<TextBox.Text>
<Binding Path="Email"
UpdateSourceTrigger="PropertyChanged"
ValidatesOnDataErrors="True"
NotifyOnValidationError="True">
<Binding.ValidationRules>
<local:EmailValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<!-- When TemplateBinding doesn't work -->
<Border>
<Border.Background>
<Binding Path="Background"
RelativeSource="{RelativeSource TemplatedParent}"/>
</Border.Background>
</Border>
Before (single line):
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value, StringFormat={}{0:N2}, Converter={StaticResource NullToEmptyConverter}, ConverterParameter=Default, FallbackValue=N/A}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
After (structured):
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<Binding Path="Value"
StringFormat="{}{0:N2}"
Converter="{StaticResource NullToEmptyConverter}"
ConverterParameter="Default"
FallbackValue="N/A"/>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<Button Content="Submit">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="Blue"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="DarkBlue"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
{Binding PropertyName} → Keep inline