WPF 依赖属性

发布于 2024-07-10 01:28:22 字数 690 浏览 6 评论 0原文

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

这是依赖属性:

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" ,但它仍然不起作用。

我以为这应该自动工作? 或者我从根本上弄错了什么?

谢谢

I have just realized I've been coercing binding/dependency properties and not really fundamentally understanding the concept.

Heres the dependency property:

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

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

The XAML is as so:

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

I'm manually setting the Problem property to a value in the constructor of the object but it doesn't update the TextBlock accordingly . . . any ideas? I've tried Mode="OneWay" and Mode="TwoWay" on the binding and it still doesn't work.

I thought this was supposed to work automatically? Or am i fundamentally getting something wrong?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

醉态萌生 2024-07-17 01:28:30

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

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

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

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

There are two ways to understand the reason of problem that you described.

At first - you should try to set property changed handler (in dependency property declaration) and put the breakpoint there. You will see whether your property is changing or not.

At second - you should check the type of dependency property owner.

Could you please show full xaml and codebehind?

黑白记忆 2024-07-17 01:28:29

这是一个设置在其中的窗口。

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 属性(即通过单击按钮),它永远不会使用新值更新 TextBlock

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.

岁月苍老的讽刺 2024-07-17 01:28:29

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

公共静态只读 DependencyProperty ProblemProperty =
DependencyProperty.Register(
“问题”,
类型(字符串),
typeof(TextBox));

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

In your code you register the Dependency Property for the class TextBox (last line of quotation).

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

So you can set a value for the ProblemProperty only for textboxes, but I cannot find any textbox in any of the code snippets.
You should register your dependency property for the type, to which the value will be assigned, from your sample the right choice is not obvious to me.
You could, as Micah does, define it to be a DP of the window, then set the property on your instantiated window. Or you could define it to any named dependency object inside the window, i.e. some object with Name=m_ContentElement, and then set your binding to
{Binding ElementName=m_ContentElement, Path=Problem}
or shorter:
{Binding Problem, ElementName=m_ContentElement}

凉城已无爱 2024-07-17 01:28:28

尝试使用 typeof(object) 而不是 typeof(string)

try the typeof(object) instead of typeof(string).

丢了幸福的猪 2024-07-17 01:28:25

您可以在这里使用 ElementName Binding ,元素将是窗口本身。

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

You can use ElementName Binding here , element will be the Window itself.

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

嘿咻 2024-07-17 01:28:24

您遇到的问题肯定与您的 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}" />

The problem your having is definitely related to your DataContext. The {Binding} extension needs to know where the property lives that you are binding to. The default location it looks at is the elements DataContext which by default is always set to the DataContext of it's parent element. If you walk the DataContext up the logical tree to the parent window, The DataContext would be null (because the DataContext of your window is null). Therefore your {Binding} on your textblock is saying "Bind my Text property to the Problem roperty of my DataContext...which is null.

There are a couple of ways to solve this. One would be to do just like Jobi mentioned and set the Element property of you binding to point to the Window where the DependencyProperty is defined like this:

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

Another option would be to set the DataContext of your Window to point to itself. That way all the elements contained in it's content will all have the DataContext of the window.

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

Now anytime you need to binding to properties defined in the window (like your Problem dependency property), then you can just do this:

<TextBlock Text="{Binding Problem}" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文