WPF DependencyProperties

时间:2008-11-25 16:27:34

标签: wpf dependency-properties

我刚刚意识到我一直在强制绑定/依赖属性,而不是从根本上理解这个概念。

继承人属性:

public string Problem
{
    get { return (string)GetValue(ProblemProperty); }
    set { SetValue(ProblemProperty, value); }
}

public static readonly DependencyProperty ProblemProperty =
    DependencyProperty.Register(
    "Problem",
    typeof(string),
    typeof(TextBox));

XAML如此:

<TextBlock Text="{Binding Path=Problem}"/>

我手动将Problem属性设置为对象构造函数中的值,但不会相应地更新TextBlock。 。 。有任何想法吗?我在绑定上尝试了Mode="OneWay"Mode="TwoWay",但仍然无效。

我认为这应该自动运行?或者我从根本上弄错了什么?

由于

6 个答案:

答案 0 :(得分:11)

您遇到的问题肯定与您的DataContext有关。 {Binding}扩展需要知道您绑定的属性所在的位置。它查看的默认位置是元素DataContext,默认情况下,它始终设置为其父元素的DataContext。如果将DataContext从逻辑树向上移动到父窗口,则DataContext将为null(因为窗口的DataContext为null)。因此,你的文本块上的{Binding}正在说“将我的Text属性绑定到我的DataContext的问题属性......这是空的。

有几种方法可以解决这个问题。就像Jobi提到的一样,将绑定的Element属性设置为指向DependencyProperty定义的Window,如下所示:

<TextBlock Text="{Binding Path=Problem,ElementName=_window}" />

另一种选择是将Window的DataContext设置为指向自身。这样,它内容中包含的所有元素都将具有窗口的DataContext。

<Window ....
        DataContext="{Binding RelativeSource={RelativeSource Self}}">

现在,只要你需要绑定到窗口中定义的属性(比如你的问题依赖属性),你就可以这样做:

<TextBlock Text="{Binding Problem}" />

答案 1 :(得分:2)

您可以在此处使用ElementName Binding,element将是Window本身。

<Window x:Class="WpfToolTip.Window1"
x:Name="_window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel>
        <Button Click="OnClick" Content="OK" />
        <Button Click="OnCancel" Content="Cancel" />
        <TextBlock Text="{Binding Path=Problem,ElementName=_window}" />
</StackPanel>

答案 2 :(得分:2)

尝试使用typeof(object)代替typeof(string)

答案 3 :(得分:0)

这是一个设置的窗口。

public partial class Window1 : Window
{
    public string Problem
    {
        get { return (string)GetValue(ProblemProperty); }
        set { SetValue(ProblemProperty, value); }
    }

    public static readonly DependencyProperty ProblemProperty =
                    DependencyProperty.Register(
                    "Problem",
                    typeof(string),
                    typeof(Window1));


    public Window1()
    {
        InitializeComponent();

        Problem = "ifowiof";
    }

    public void OnClick(object sender, EventArgs e)
    {
        Problem = "behl";
    }

    public void OnCancel(object sender, EventArgs e)
    {
       Problem = "eioeopje";
    }
}

XAML:

<Window x:Class="WpfToolTip.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <StackPanel>
            <Button Click="OnClick" Content="OK" />
            <Button Click="OnCancel" Content="Cancel" />
            <TextBlock Text="{Binding Path=Problem}" />
    </StackPanel>
</Window>

如果我在加载时设置RelativeSource,就像你说的那样,但是如果我手动更改代码中的Problem属性(即通过按钮点击),它永远不会更新{{1}使用新值。

答案 4 :(得分:0)

在您的代码中,您为类TextBox(最后一行引用)注册了Dependency属性。

  

public static readonly DependencyProperty ProblemProperty =
     DependencyProperty.Register(
     “问题”,
     typeof运算(字符串),
     typeof运算(文本框));

因此,您只能为文本框设置ProblemProperty的值,但我在任何代码段中都找不到任何文本框。 您应该从样本中注册要为其分配值的类型的依赖项属性,对我来说,正确的选择并不明显。 你可以像Micah那样将它定义为窗口的DP,然后在实例化窗口中设置属性。或者您可以将其定义为窗口内的任何命名依赖项对象,即具有Name = m_ContentElement的某个对象,然后将绑定设置为
{Binding ElementName=m_ContentElement, Path=Problem}或更短:
{Binding Problem, ElementName=m_ContentElement}

答案 5 :(得分:0)

有两种方法可以理解您描述的问题原因。

首先 - 您应该尝试设置属性更改处理程序(在依赖项属性声明中)并将断点放在那里。您将看到您的房产是否正在改变。

第二个 - 你应该检查依赖属性所有者的类型。

你能否展示完整的xaml和codebehind?