6

我刚刚意识到我一直在强制绑定/依赖属性,并没有真正从根本上理解这个概念。

继承人的依赖属性:

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"还是不行。

我以为这应该自动工作?还是我从根本上搞错了什么?

谢谢

4

6 回答 6

11

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

有几种方法可以解决这个问题。一种方法是像 Jobi 提到的那样做,并将绑定的 Element 属性设置为指向 DependencyProperty 定义如下的窗口:

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

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

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

现在,只要您需要绑定到窗口中定义的属性(例如您的 Problem 依赖项属性),您就可以这样做:

<TextBlock Text="{Binding Problem}" />
于 2008-11-25T16:35:23.243 回答
2

您可以在此处使用 ElementName 绑定,元素将是 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>

于 2008-11-25T18:10:38.947 回答
2

尝试typeof(object)代替typeof(string).

于 2012-03-22T10:07:41.623 回答
0

Its a Window this is set in.

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>

It works if I set the RelativeSource like you said when it loads, but if i change the Problem property in code manually (ie. via a button click) it never updates the TextBlock with the new value.

于 2008-11-25T17:30:14.660 回答
0

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

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

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

于 2009-02-23T21:12:01.877 回答
0

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

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

其次 - 您应该检查依赖属性所有者的类型。

您能否显示完整的 xaml 和代码隐藏?

于 2010-08-26T12:57:01.453 回答