问题
I'm creating a simple User Control in WPF that contains a TextBlock inside a Button.
<UserControl x:Class="WpfExpansion.MyButton"..... >
<Grid >
<Button Background="Transparent" >
<TextBlock Text="{Binding Path=Text}"/>
</Button>
</Grid>
</UserControl>
And also the "Text" dependency property.
public partial class MyButton : UserControl
{
public MyButton()
{
InitializeComponent();
this.DataContext = this;
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(MyButton), new PropertyMetadata(string.Empty));
}
And then I use the UserControl like this:
<MyButton Text="Test" />
The problem is that the Visual Studio design does not change, but it works in runtime.
What is wrong?
I also tried
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Inside the UC definition, without success.
回答1:
Try using FrameworkPropertyMetadata
instead of PropertyMetadata
, specifying AffectsRender
like below, then restart Visual Studio:
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(MyButton),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.AffectsRender));
MSDN Documentation about FrameworkPropertyMetadataOptions.AffectsRender
says
Some aspect of rendering or layout composition (other than measure or arrange) is affected by value changes to this dependency property.
For other cases, there are options like AffectsMeasure, AffectsArrange, etc.
回答2:
Golden shovel candidate, still I came across the same problem and had it solved being inspired by https://www.codeproject.com/Questions/1096567/How-to-set-a-custom-dependency-property-of-user-co
Long story short: your dependency property is set on the UserControl
itself and you are trying to bind the it's child property to it. The child's binding needs to have RelativeSource
defined, hence the TextBlock
should look like this:
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=Text}" />
The only DataContext
assignment needed is the one you already have in the code behind in the constructor.
UPDATE
But then I tried your attempts and came to the conclusion that if you define theDataContext
in XAML already, you don't need to provide it in each of the controls. This means you need to define your UC the following way (d:DataContext=...
does the trick):
<UserControl x:Class="WpfExpansion.MyButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:YRS100_Data_Analysis"
mc:Ignorable="d"
d:DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<Button Background="Transparent">
<TextBlock Text="{Binding Path=Text}" />
</Button>
</Grid>
</UserControl>
Works like a charm.
来源:https://stackoverflow.com/questions/18158500/usercontrol-dependency-property-design-time