XAML 为什么我不能绑绳子?

qmelpv7a  于 2022-12-07  发布在  其他
关注(0)|答案(4)|浏览(107)

尝试用我以前的大脑来研究WPF数据绑定。从我能想到的最简单的场景开始:一个在线的例子,然后我简化了它。
我把一个简单的string属性绑定到一个TextBlock上。没有用。当我把这个string封装到我自己的类中时,它就很好用了!
问:为什么我的string属性不起作用,而我的类起作用?
第一个

jchrr9hc

jchrr9hc1#

绑定对数据上下文进行操作,该数据上下文是通过DataContext属性在从FrameworkElement派生的元素上设置的。数据上下文在元素树中继承。
在XAML元素上声明数据绑定时,它们通过查看其直接的DataContext属性来解析数据绑定。数据上下文通常是用于绑定源值路径计算的绑定源对象。可以在绑定中重写此行为并设置特定的绑定源对象值。如果未设置承载绑定的对象的DataContext属性,父元素的DataContext属性会被检查,依此类推,直到XAML对象树的根。简而言之,除非在对象上显式设置,否则用于解析绑定的数据上下文将从父元素继承。
如果没有数据上下文集,或者需要引用其他元素作为绑定源,则需要使用SourceElementNameRelativeSource参数化Binding
可以将绑定配置为使用特定对象进行解析,而不是使用数据上下文进行绑定解析。
让我们回顾一下如何绑定在MainWindow中定义的属性。最初没有分配数据上下文。因此,所有到Name1的绑定都将失败。我们能做些什么?这里有几个选项(还有更多)。

  • 在代码隐藏中将MainWindowDataContext设置为this
public MainWindow()
{
    InitializeComponent();
    DataContext = this;            
}

这意味着所有控件都继承MainWindow作为绑定源。因此,我们可以像这样绑定Name1属性:

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

这里的Name1是绑定源上要绑定的属性的名称(或property path)。因此,如果我们简单地将Name1直接赋值为窗口的DataContext,那么我们需要引用绑定源本身,这是{Binding}在没有属性路径的情况下所做的事情。
第一次

  • 如果您没有设定DataContext,您仍然可以使用ElementName(需要将x:Name指派给目的控件)或RelativeSource来指涉项目,RelativeSource会指涉项目树形结构中的项目,从目前的项目周游父代,直到到达根。
<TextBlock Text="{Binding Name1, RelativeSource={RelativeSource AncestorType={x:Type local:MainWindow}}}"/>

此示例转换为:在元素树中向上搜索MainWindow类型的绑定源,如果找到它,则绑定到它的Name1属性。正如您所看到的,如果该属性是在控件本身上定义的(如示例中所示),则不一定需要数据上下文。不过,通常情况下,如果没有任何限制,您将使用DataContext属性,因为它可以方便地继承。
我希望您看到它并没有什么特别之处。关于绑定sytax(可能会让人感到困惑),有一个很好的文档可以帮您解决很多疑问:

我不由得想:字符串类中的哪个字段,或者更确切地说,哪个属性实际上保存了字符串的“值”?

**Bonus round:**您完全不需要担心这个问题。您绑定到string属性,WPF知道如何显示它,不需要使用内部结构,但是出于教育目的,文档声明:

字符串是用于表示文本的字符的顺序集合。String对象是表示字符串的System.Char对象的顺序集合; System.Char对象对应于UTF-16代码单元。String对象的值是System.Char对象的顺序集合的内容,并且该值是不可变的(即,它是只读的)。
string型别会以其索引子属性Chars公开这个字符数组。

mpgws1up

mpgws1up2#

因为绑定到字符串时,绑定到的对象中没有Name1inside,也就是说,Name1中没有Name1Name1.Name1的结果是什么?),但是,Employee对象中有Name1Employee.Name1的结果是什么?)

ghhaqwfi

ghhaqwfi3#

如果要访问MainWindowName1属性,应将DataContext设置为this(即MainWindow示例),而不是Name1

using System.Windows;

namespace DataBindingOneWay
{
    public partial class MainWindow : Window
    {
        public class Employee
        {
            public string? Name1 { get; set; } = "Paul";
        }

        public string? Name1 { get; set; } = "Peter";

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;            
        }
    }
}

或从另一端-当您希望将Name1属性设置为MainWindowDataContext时,您的绑定应如下所示:

<Window x:Class = "DataBindingOneWay.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Height = "350" Width = "600">
    <Grid>
        <StackPanel Orientation = "Vertical" HorizontalAlignment="Center" Margin="0,100,0,0">
            <TextBlock Text="{Binding}" />
        </StackPanel>
    </Grid>
</Window>
kuhbmx9i

kuhbmx9i4#

多亏了乔纳森鼓舞人心的回答,我不得不想:字符串类中的哪个字段,或者更确切地说,哪个属性实际上保存了字符串的“值”?
我玩了所有的东西,但似乎没有什么东西能抓住真正的绳子!(奇怪)。这就是我有一个疯狂的想法,并尝试简单

<TextBlock Text="{Binding}" />

还有

DataContext = Name1;

而且......成功了!

相关问题