为什么绑定的DataContext主窗口XAML中失败同一作为与this.datacontext代码隐藏绑定=呢? [英] Why does binding the MainWindow datacontext in XAML fail to act the same as binding in the codebehind with this.datacontext=this?

查看:602
本文介绍了为什么绑定的DataContext主窗口XAML中失败同一作为与this.datacontext代码隐藏绑定=呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用数据绑定到一个ObservableCollection绑定到一个DataGrid的ItemsSource时,我了解WPF和东西。



我在代码隐藏可以设置 this.DataContext =这个DataContext的; bloopDataGrid.DataContext =这一点; 。那好得很。



我想我可以尝试像

 < Window.DataContext> 
<局部:主窗口/>
< /Window.DataContext>

在我的主窗口,而这将导致在的这个问题。好吧,这使得一些感觉。



在阅读并其他问题/回答是说去尝试的DataContext ={绑定的RelativeSource = {的RelativeSource自}}在窗口的XAML代码,我以为我可以的真正做到这一点的。显然,我的不能。或者至少,在IDE让我和它的语法正确,但不会做我想做的。(也就是说,到底是什么 this.DataContext =这一点; 一样)



然后我读关于使用{绑定的ElementName =,路径=},并试图使用它像这样:

 <数据网格
名称=bloopDataGrid
Grid.Row =1
的ItemsSource ={结合的ElementName = testWin,路径= OutputCollection}>
< / DataGrid的>



这也不起作用。也许不是出于同样的原因,但我不能用它找出问题。



奇怪的是,我不能复制中的雷切尔林的博客文章



XAML:

 <窗口
X:类=DataBinding.MainWindow
的xmlns =http://schemas.microsoft .COM / WinFX的/ 2006 / XAML /演示
的xmlns:X =http://schemas.microsoft.com/winfx/2006/xaml
标题=主窗口
高度=350
WIDTH =525
X:NAME =testWin>
<网格和GT;
< Grid.RowDefinitions>
< RowDefinition />
< RowDefinition />
< /Grid.RowDefinitions>

<标签Grid.Row =0CONTENT ={结合文字}>
< /标签>

<数据网格
NAME =bloopDataGrid
Grid.Row =1
的ItemsSource ={绑定路径= OutputCollection}>
< / DataGrid的>
< /网格和GT;
< /窗GT;



C#:



 使用系统; 
使用System.Collections.ObjectModel; //为的ObservableCollection< T>使用System.Windows
;

命名空间数据绑定
{
公共部分类主窗口:窗口
{
公共字符串文本{搞定;组; }
公众的ObservableCollection< testStruct> OutputCollection {搞定;组; }

公共结构testStruct
{
公共testStruct(字符串x,y字符串):这个()
{
COL1 = X;
col2的= Y;
}
公共字符串COL1 {搞定;组; }
公共字符串col2的{搞定;组; }
}

公共主窗口()
{
的InitializeComponent();

种皮T1 =新种皮();
this.DataContext =这一点;
//this.DataContext = T1;
//bloopDataGrid.DataContext =这一点;
文本=绑定\this\;
t1.text =约束类;

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

公共类种皮
{
公共字符串文本{搞定;组; }
}

}
}



上面的代码是我用什么来测试这一点,目前正在使用的代码隐藏版本,它正确地给了我





我是什么做错了,这是阻止我得到相同的结果上面的图片但通过使用XAML的DataContext的处理?我不能正确连接点? ?......我错过了一些点


解决方案

 < Window.DataContext> 
<局部:主窗口/>
< /Window.DataContext>



是不一样的。



  this.DataContext =这一点; 



第一个是创造了一个新的实例主窗口类,并分配了到窗口的的DataContext 属性,而第二个是分配非常相同的实例的窗口的DataContext 属性。



在为了实现这一XAML中,你需要使用的 的RelativeSource >绑定:

 <窗口的DataContext ={绑定的RelativeSource = {自我的RelativeSource}}> 
< /窗GT;



编辑:



确定之间的行为差​​异的DataContext 在XAML和代码背后是事实,当构造函数完成执行XAML被实际分析,因为造成的调度等待用户代码(在窗口的构造函数)执行其挂起操作之前完成。



这导致实际属性值将在这些不同时刻不同,因为没有 INotifyPropertyChanged的,WPF没有更新的用户界面,以反映新的价值观的方式。



实施 INotifyPropertyChanged的窗口本身,但我建议这个创建视图模型,因为我不喜欢混合 INotifyPropertyChanged的的事实(这更是一个视图模型的概念)与的DependencyObject 派生类(UI元素)。


I am trying to use Data binding to bind an ObservableCollection to the ItemsSource of a DataGrid, as I learn about WPF and stuff.

In the code-behind I can set the DataContext with this.DataContext = this; or bloopDataGrid.DataContext = this;. That's fine and dandy.

I thought I could try something like

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

in my main window, but this causes a Stack Overflow Exception as explained in this question. Fine, that makes some sense.

After reading this and other questions/answers that say to try DataContext="{Binding RelativeSource={RelativeSource Self}}" in the window's XAML code, I thought I could actually do this. Apparently I cannot. Or at least, the IDE lets me and it's syntactically correct, but does not do what I want (ie, exactly what this.DataContext = this; does).

Then I read this about using "{Binding ElementName=, Path=}" and tried to use it like so:

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

Which also doesn't work. Maybe not for the same reason, but I can't figure out the problem with it.

Oddly, I can't replicate the rebinding example shown in Rachel Lim's blog post.

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

    }
}

The above code is what I'm using to test this, and is currently using the code-behind version which correctly gives me

What am I doing wrong, which is preventing me from getting the same results as the above picture but by using XAML for the DataContext handling? Am I not connecting the dots properly? ...am I missing some dots?

解决方案

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

is not the same as

this.DataContext = this;

The first one is creating a new instance of the MainWindow class and assigning that to the DataContext property of the Window, while the second is assigning the very same instance of the Window to its DataContext property.

In order to achieve that in XAML, you need to use a RelativeSource Binding:

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

Edit:

The difference in behavior between defining the DataContext in XAML and in code behind is caused by the fact that the XAML is actually parsed when the constructor finishes executing, because the Dispatcher waits for the user code (in the constructor of the Window) to finish before executing its pending operations.

This causes the actual property values to be different in these different moments, and since there is no INotifyPropertyChanged, WPF has no way of updating the UI to reflect the new values.

You could implement INotifyPropertyChanged in the Window itself, but I suggest creating a ViewModel for this, as I don't like the fact of mixing INotifyPropertyChanged (which is more of a ViewModel concept) with DependencyObject-derived classes (UI elements).

这篇关于为什么绑定的DataContext主窗口XAML中失败同一作为与this.datacontext代码隐藏绑定=呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆