Using XAML Property Element Syntax
Convert long inline bindings to structured Property Element Syntax for improved readability.
Problem
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}}"/>
Solution
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>
When to Use
Condition Use Property Element Syntax
Line > 100 characters Yes
Nested RelativeSource Yes
MultiBinding Yes
Multiple BindingValidationRules Yes
Simple binding No (keep inline)
Common Patterns
RelativeSource Binding
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>
MultiBinding
<TextBlock> <TextBlock.Text> <MultiBinding Converter="{local:FullNameConverter}"> <Binding Path="FirstName"/> <Binding Path="LastName"/> </MultiBinding> </TextBlock.Text> </TextBlock>
Binding with Validation
<TextBox> <TextBox.Text> <Binding Path="Email" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True" NotifyOnValidationError="True"> <Binding.ValidationRules> <local:EmailValidationRule/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox>
TemplateBinding Alternative
<!-- When TemplateBinding doesn't work --> <Border> <Border.Background> <Binding Path="Background" RelativeSource="{RelativeSource TemplatedParent}"/> </Border.Background> </Border>
Complex Example
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>
Style Property Element
<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>
Formatting Guidelines
-
One attribute per line when using Property Element
-
Indent nested elements consistently (4 spaces or 1 tab)
-
Align closing tags with opening tags
-
Group related properties together
Checklist
-
Line exceeds 100 characters → Use Property Element
-
Contains nested markup extension → Use Property Element
-
Simple {Binding PropertyName} → Keep inline
-
Has multiple Binding properties → Consider Property Element
-
Contains ValidationRules → Use Property Element