尝试用我以前的大脑来研究WPF数据绑定。从我能想到的最简单的场景开始:一个在线的例子,然后我简化了它。我把一个简单的string属性绑定到一个TextBlock上。没有用。当我把这个string封装到我自己的类中时,它就很好用了!问:为什么我的string属性不起作用,而我的类起作用?第一个
string
TextBlock
jchrr9hc1#
绑定对数据上下文进行操作,该数据上下文是通过DataContext属性在从FrameworkElement派生的元素上设置的。数据上下文在元素树中继承。在XAML元素上声明数据绑定时,它们通过查看其直接的DataContext属性来解析数据绑定。数据上下文通常是用于绑定源值路径计算的绑定源对象。可以在绑定中重写此行为并设置特定的绑定源对象值。如果未设置承载绑定的对象的DataContext属性,父元素的DataContext属性会被检查,依此类推,直到XAML对象树的根。简而言之,除非在对象上显式设置,否则用于解析绑定的数据上下文将从父元素继承。如果没有数据上下文集,或者需要引用其他元素作为绑定源,则需要使用Source、ElementName或RelativeSource参数化Binding。可以将绑定配置为使用特定对象进行解析,而不是使用数据上下文进行绑定解析。让我们回顾一下如何绑定在MainWindow中定义的属性。最初没有分配数据上下文。因此,所有到Name1的绑定都将失败。我们能做些什么?这里有几个选项(还有更多)。
DataContext
FrameworkElement
Source
ElementName
RelativeSource
Binding
MainWindow
Name1
this
public MainWindow() { InitializeComponent(); DataContext = this; }
这意味着所有控件都继承MainWindow作为绑定源。因此,我们可以像这样绑定Name1属性:
<TextBlock Text="{Binding Name1}"/>
这里的Name1是绑定源上要绑定的属性的名称(或property path)。因此,如果我们简单地将Name1直接赋值为窗口的DataContext,那么我们需要引用绑定源本身,这是{Binding}在没有属性路径的情况下所做的事情。第一次
{Binding}
x:Name
<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公开这个字符数组。
String
System.Char
Chars
mpgws1up2#
因为绑定到字符串时,绑定到的对象中没有Name1inside,也就是说,Name1中没有Name1(Name1.Name1的结果是什么?),但是,Employee对象中有Name1(Employee.Name1的结果是什么?)
Name1.Name1
Employee
Employee.Name1
ghhaqwfi3#
如果要访问MainWindow的Name1属性,应将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属性设置为MainWindow的DataContext时,您的绑定应如下所示:
<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>
kuhbmx9i4#
多亏了乔纳森鼓舞人心的回答,我不得不想:字符串类中的哪个字段,或者更确切地说,哪个属性实际上保存了字符串的“值”?我玩了所有的东西,但似乎没有什么东西能抓住真正的绳子!(奇怪)。这就是我有一个疯狂的想法,并尝试简单
<TextBlock Text="{Binding}" />
还有
DataContext = Name1;
而且......成功了!
4条答案
按热度按时间jchrr9hc1#
绑定对数据上下文进行操作,该数据上下文是通过
DataContext
属性在从FrameworkElement
派生的元素上设置的。数据上下文在元素树中继承。在XAML元素上声明数据绑定时,它们通过查看其直接的DataContext属性来解析数据绑定。数据上下文通常是用于绑定源值路径计算的绑定源对象。可以在绑定中重写此行为并设置特定的绑定源对象值。如果未设置承载绑定的对象的DataContext属性,父元素的DataContext属性会被检查,依此类推,直到XAML对象树的根。简而言之,除非在对象上显式设置,否则用于解析绑定的数据上下文将从父元素继承。
如果没有数据上下文集,或者需要引用其他元素作为绑定源,则需要使用
Source
、ElementName
或RelativeSource
参数化Binding
。可以将绑定配置为使用特定对象进行解析,而不是使用数据上下文进行绑定解析。
让我们回顾一下如何绑定在
MainWindow
中定义的属性。最初没有分配数据上下文。因此,所有到Name1
的绑定都将失败。我们能做些什么?这里有几个选项(还有更多)。MainWindow
的DataContext
设置为this
。这意味着所有控件都继承
MainWindow
作为绑定源。因此,我们可以像这样绑定Name1
属性:这里的
Name1
是绑定源上要绑定的属性的名称(或property path)。因此,如果我们简单地将Name1
直接赋值为窗口的DataContext
,那么我们需要引用绑定源本身,这是{Binding}
在没有属性路径的情况下所做的事情。第一次
DataContext
,您仍然可以使用ElementName
(需要将x:Name
指派给目的控件)或RelativeSource
来指涉项目,RelativeSource
会指涉项目树形结构中的项目,从目前的项目周游父代,直到到达根。此示例转换为:在元素树中向上搜索
MainWindow
类型的绑定源,如果找到它,则绑定到它的Name1
属性。正如您所看到的,如果该属性是在控件本身上定义的(如示例中所示),则不一定需要数据上下文。不过,通常情况下,如果没有任何限制,您将使用DataContext
属性,因为它可以方便地继承。我希望您看到它并没有什么特别之处。关于绑定sytax(可能会让人感到困惑),有一个很好的文档可以帮您解决很多疑问:
我不由得想:字符串类中的哪个字段,或者更确切地说,哪个属性实际上保存了字符串的“值”?
**Bonus round:**您完全不需要担心这个问题。您绑定到
string
属性,WPF知道如何显示它,不需要使用内部结构,但是出于教育目的,文档声明:字符串是用于表示文本的字符的顺序集合。
String
对象是表示字符串的System.Char
对象的顺序集合;System.Char
对象对应于UTF-16代码单元。String
对象的值是System.Char
对象的顺序集合的内容,并且该值是不可变的(即,它是只读的)。string
型别会以其索引子属性Chars
公开这个字符数组。mpgws1up2#
因为绑定到字符串时,绑定到的对象中没有
Name1
inside,也就是说,Name1
中没有Name1
(Name1.Name1
的结果是什么?),但是,Employee
对象中有Name1
(Employee.Name1
的结果是什么?)ghhaqwfi3#
如果要访问
MainWindow
的Name1
属性,应将DataContext
设置为this
(即MainWindow示例),而不是Name1
。或从另一端-当您希望将
Name1
属性设置为MainWindow
的DataContext
时,您的绑定应如下所示:kuhbmx9i4#
多亏了乔纳森鼓舞人心的回答,我不得不想:字符串类中的哪个字段,或者更确切地说,哪个属性实际上保存了字符串的“值”?
我玩了所有的东西,但似乎没有什么东西能抓住真正的绳子!(奇怪)。这就是我有一个疯狂的想法,并尝试简单
还有
而且......成功了!