UserControl Dependency Property design time

↘锁芯ラ 提交于 2019-12-05 21:35:26

问题


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



来源:https://stackoverflow.com/questions/18158500/usercontrol-dependency-property-design-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!