gpt4 book ai didi

c# - 为什么在 XAML 中绑定(bind) MainWindow datacontext 无法像在代码隐藏中使用 this.datacontext=this 绑定(bind)一样?

转载 作者:可可西里 更新时间:2023-11-01 08:02:39 26 4
gpt4 key购买 nike

我正在尝试使用数据绑定(bind)将 ObservableCollection 绑定(bind)到 DataGrid 的 ItemsSource,因为我了解了 WPF 和其他东西。

在代码隐藏中,我可以使用 this.DataContext = this;bloopDataGrid.DataContext = this; 设置 DataContext。那很好,花花公子。

我想我可以试试类似的东西

<Window.DataContext>
<local:MainWindow/>
</Window.DataContext>

在我的主窗口中,但这会导致堆栈溢出异常,如 this question 中所述。 .好吧,这有点道理。

看完this以及其他在窗口的 XAML 代码中尝试 DataContext="{Binding RelativeSource={RelativeSource Self}}" 的问题/答案,我认为我可以实际执行此操作。显然我不能。或者至少,IDE 允许我并且它在语法上是正确的,但没有做我想要的(即,正是 this.DataContext = this; 所做的)。

然后我读了this关于使用 "{Binding ElementName=, Path=}" 并尝试像这样使用它:

<DataGrid
Name="bloopDataGrid"
Grid.Row="1"
ItemsSource="{Binding ElementName=testWin, Path=OutputCollection}">
</DataGrid>

这也行不通。也许不是出于同样的原因,但我无法弄清楚它的问题。

奇怪的是,我无法复制 Rachel Lim's blog post 中显示的重新绑定(bind)示例.

XAML:

<Window
x:Class="DataBinding.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"
x:Name="testWin">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>

<Label Grid.Row="0" Content="{Binding text}">
</Label>

<DataGrid
Name="bloopDataGrid"
Grid.Row="1"
ItemsSource="{Binding Path=OutputCollection}">
</DataGrid>
</Grid>
</Window>

C#:

using System;
using System.Collections.ObjectModel; //For ObservableCollection<T>
using System.Windows;

namespace DataBinding
{
public partial class MainWindow : Window
{
public String text { get; set; }
public ObservableCollection<testStruct> OutputCollection { get; set; }

public struct testStruct
{
public testStruct(String x, String y) : this()
{
Col1 = x;
Col2 = y;
}
public String Col1 { get; set; }
public String Col2 { get; set; }
}

public MainWindow()
{
InitializeComponent();

testA t1 = new testA();
this.DataContext = this;
//this.DataContext = t1;
//bloopDataGrid.DataContext = this;
text = "bound \"this\"";
t1.text = "bound a class";

OutputCollection = new ObservableCollection<testStruct>();
OutputCollection.Add(new testStruct("1", "2"));
OutputCollection.Add(new testStruct("3", "4"));
}

public class testA
{
public String text { get; set; }
}

}
}

上面的代码是我用来测试的,目前正在使用正确给我的代码隐藏版本

In codebehind

我做错了什么,这阻止了我通过使用 XAML 进行 DataContext 处理而无法获得与上图相同的结果?我没有正确连接点吗? ...我是否遗漏了一些点?

最佳答案

<Window.DataContext>
<local:MainWindow/>
</Window.DataContext>

不等于

this.DataContext = this;

第一个是创建 MainWindow 类的新实例并将其分配给 WindowDataContext 属性,而第二个正在将 Window 的同一个实例分配给它的 DataContext 属性。

为了在 XAML 中实现这一点,您需要使用 RelativeSource绑定(bind):

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

编辑:

在 XAML 和代码隐藏中定义 DataContext 的行为差异是由于 XAML 在构造函数完成执行时实际被解析,因为 Dispatcher 在执行未决操作之前等待用户代码(在 Window 的构造函数中)完成。

这会导致实际属性值在这些不同时刻不同,并且由于没有 INotifyPropertyChanged,WPF 无法更新 UI 以反射(reflect)新值。

可以Window 本身中实现INotifyPropertyChanged,但我建议为此创建一个ViewModel,因为我不喜欢这个事实将 INotifyPropertyChanged(这更像是一个 ViewModel 概念)与 DependencyObject 派生类(UI 元素)混合。

关于c# - 为什么在 XAML 中绑定(bind) MainWindow datacontext 无法像在代码隐藏中使用 this.datacontext=this 绑定(bind)一样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15205280/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com