从XAML绑定到代码后台的数据绑定

14

我在代码后台有这个Text依赖属性:

public static DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(MainWindow),
        new PropertyMetadata("Hello world"));

public string Text {
    get { return (string)GetValue(TextProperty); }
    set { SetValue(TextProperty, value); }
}

我想将标签的内容绑定到Text属性,以便标签显示Text属性的实际值,反之亦然。

<Label Content="{Binding ???}" />

我该怎么做?

我以前做过这个,但现在我不记得怎么做了 - 而且它非常简单。最简单的代码将被接受。


我已经尝试过这个代码:<Label Content="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfApplication1:MainWindow}}, Path=Text}" />,但它仍然无法工作...难道绑定在全新的WPF项目中不起作用吗?在其他方面都正常的情况下? - Rasto
4个回答

18

将您的窗口/控件的DataContext设置为相同的类,然后在绑定中指定路径,例如:

public class MyWindow : Window {
public MyWindow() { InitializeComponents(); DataContext = this; }
public string Text { ... } }

然后在您的 XAML 中:

<Label Content="{Binding Path=Text}">

可以了,谢谢。但是为什么在VS设计器中它不显示“Label”的内容?! - Rasto
当从代码后台设置DataContext时,Blend不会显示绑定到数据上下文的数据。您可以使用d:DataContext将设计时数据上下文设置为另一个对象,这有助于在Blend中进行设计。请参见此处:https://dev59.com/L3RA5IYBdhLWcg3wsgFP - Hadi Eskandari
我不想在Blend中使用它,而是在VisualStudio中。这两者一样吗? - Rasto
我尝试将 DataContext="{Binding RelativeSource={RelativeSource Self}}" 放入 XAML 代码中,但是 VS 仍然不会在 Label 中显示绑定的数据。你有同样的经历吗?或者你的 VS 在可视化设计师中显示绑定的数据? - Rasto
1
如果您设置Label的DataContext属性,那么您基本上是将其设置为自身。Label恰好具有Text属性,因此您可能不会看到任何数据绑定错误。您需要将数据上下文设置为{RelativeSource FindAncestor,AncestorType = {x:Type Window}}或类似的内容。 - Kevin Hsu

13

你需要设置窗口的DataContext才能使它工作。XAML:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" 
        DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
      <StackPanel>
        <Label Content="{Binding Text}" />
        <Button Content="Click me" Click="HandleClick" />
      </StackPanel>

    </Grid>
</Window>

代码后端:

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(MainWindow), new PropertyMetadata("Hello world"));
    public string Text 
    { 
        get { return (string)GetValue(TextProperty); } 
        set { this.SetValue(TextProperty, value); } 
    }

    public MainWindow()
    {
        InitializeComponent();
    }

    protected void HandleClick(object sender, RoutedEventArgs e)
    {
        this.Text = "Hello, World";
    }
}

3
抱歉,我忘记了DataContext。现在请再试一次。抱歉。(测试过了,现在可以用了。) - Ari Roth
+1 更好了,但其他人更快,在你编辑之前。无论如何,感谢你提供的好例子,它对其他人会有用。 - Rasto
我更喜欢这种方法,因为你不必查看代码后台即可查看DataContext分配。但是,如果您发现自己将2个或3个以上的内容绑定到代码后台,则应该真正考虑将它们拆分为ViewModel! - piedar

3

在XAML中将DataContext设置到代码后台可能有些棘手,但通常情况下这些情况是最常见的:

  1. 您希望将DataContext设置为整个Window或自定义UserControl

.

<Window
blahhhh..
DataContext={Binding RelativeSource={RelativeSource Mode=Self}}>

或者

<UserControl
Blahhhh....
DataContext={Binding RelativeSource={RelativeSource Mode=Self}}>

2. 如果您将窗口或用户控件的 DataContext 设置为代码后台以外的其他内容,并且有子控件,则需要将其 DataContext 设置为代码后台,您可以使用以下方法:

<Label DataContext={Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}/>

对于自定义UserControl

<Label DataContext={Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=UserControl}}/>

在这种情况下,将 DataContext设置为self,将使绑定引用标签对象本身,而不是控件的代码后台。希望这能帮到你。

1

当你说它在代码后面时,你是指在你的类的窗口代码中吗?

你可能想要绑定到RelativeSource,其中祖先类型为Window。或者,如果您的数据上下文尚未设置,在Load事件中将窗口的DataContext属性设置为窗口本身(this),然后只需使用{Binding Text}。


是的,code-behind 意味着 LabelText 依赖属性在同一个类中。这里唯一的区别是 Label 在 XAML 中,而依赖属性在代码中。 - Rasto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接