I have a custom control that binds to a complex object and binds itself to various properties in the object. One of my developers needed to be able to override one of these bindings. I wanted my custom control to be able to detect if the developer had explicitly set a Text attribute and not overwrite it with its own binding.
I found the ValueSource structure which is the subject of this interesting page.
You can use GetValueSource to get the ValueSource for a dependency property. If you also combine this with GetBindingExpression which gets the actual Binding Expression, you can figure out a lot about a DependencyProperty. In particular, you can tell if the developer explicitly set a value for a DependencyProperty.
Here's a quick demonstration. Start a new WPF C# project called ValueSource. Set MainWindow xaml and vb to this...
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:ValueSource"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Window.Resources>
<Style TargetType="TextBlock" x:Key="TestBlockStyle">
<Setter Property="Text" Value="NamedStyle"/>
</Style>
<Style TargetType="TextBlock" x:Key="StyleWithTrigger">
<Style.Triggers>
<Trigger Property="Visibility" Value="Visible">
<Setter Property="Text" Value="StyleWithTrigger"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel Orientation="Vertical">
<TextBlock Loaded="TextBlock_Loaded"/>
<TextBlock Text="Literal" Loaded="TextBlock_Loaded"/>
<TextBlock Text="{Binding TextBlock3_Text}" Loaded="TextBlock_Loaded"/>
<TextBlock Style="{StaticResource TestBlockStyle}" Loaded="TextBlock_Loaded"/>
<TextBlock Style="{StaticResource StyleWithTrigger}" Loaded="TextBlock_Loaded"/>
</StackPanel>
</Window>
-------------------------------------
public partial class MainWindow : Window
{
public String TextBlock3_Text { get { return "BoundText"; } }
InitializeComponent();
}
TextBlock tb = (TextBlock)sender;
}
}
TextBlock '' ValueSource is Default and is not bound
TextBlock 'Literal' ValueSource is Local and is not bound
TextBlock 'BoundText' ValueSource is Local and is bound
TextBlock 'NamedStyle' ValueSource is Style and is not bound
TextBlock 'StyleWithTrigger' ValueSource is StyleTrigger and is not bound
{
TextBlock tb = (TextBlock)sender;
object localValue = tb.ReadLocalValue(TextBlock.TextProperty);
Console.WriteLine($"TextBlock '{tb.Text}' LocalValue is {localValue.ToString()}");
}
TextBlock 'Literal' LocalValue is Literal
TextBlock 'BoundText' LocalValue is System.Windows.Data.BindingExpression
TextBlock 'NamedStyle' LocalValue is {DependencyProperty.UnsetValue}
TextBlock 'StyleWithTrigger' LocalValue is {DependencyProperty.UnsetValue}
No comments:
Post a Comment