简体   繁体   中英

UserControl Dependency Property design time

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.

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.

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 the DataContext 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM