14

私はWPFなどについて学んでいるので、データバインディングを使用してObservableCollectionをDataGridのItemsSourceにバインドしようとしています。

コード ビハインドでは、DataContext をthis.DataContext = this;orで設定できbloopDataGrid.DataContext = this;ます。それはいいですし、ダンディです。

私は何かを試すことができると思った

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

私のメインウィンドウで、これにより、この質問で説明されているようにスタックオーバーフロー例外が発生します。わかりました、それはある程度理にかなっています。

これDataContext="{Binding RelativeSource={RelativeSource Self}}"と、ウィンドウの XAML コードで試してみるという他の質問/回答を読んだ後、実際にこれができると思いました。どうやら私はできません。少なくとも、IDE は構文的には正しいのですが、私が望んでいることを実行しません (つまり、まさに実行することですthis.DataContext = this;)。

次に、使用についてこれを読み、"{Binding ElementName=, Path=}"次のように使用しようとしました:

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

これも機能しません。同じ理由ではないかもしれませんが、問題がわかりません。

奇妙なことに、Rachel Lim のブログ投稿に示されている再バインドの例を複製することはできません。

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

    }
}

上記のコードは、これをテストするために使用しているものであり、現在、正しく提供されるコードビハインドバージョンを使用しています

コードビハインドで

DataContext の処理に XAML を使用すると、上の図と同じ結果が得られないのですが、何が間違っていますか? ドットを正しく接続していませんか?...いくつかの点が欠けていますか?

4

1 に答える 1

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

と同じではありません

this.DataContext = this;

MainWindow1 つ目はクラスの新しいインスタンスを作成し、それを のDataContextプロパティにWindow割り当てます。2 つ目は のまったく同じインスタンスWindowをそのDataContextプロパティに割り当てます。

RelativeSourceXAML でそれを実現するには、 Bindingを使用する必要があります。

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

編集:

XAML とコード ビハインドでの の定義の動作の違いはDataContext、コンストラクターの実行が終了したときに XAML が実際に解析されるという事実が原因ですDispatcher。保留中の操作。

これにより、実際のプロパティ値がこれらのさまざまな時点で異なります。また、 がないためINotifyPropertyChanged、WPF には新しい値を反映するために UI を更新する方法がありません。

couldそれ自体で実装INotifyPropertyChangedしますが、派生クラス (UI 要素)と (ViewModel の概念に近い)Window混合するのは好きではないため、このために ViewModel を作成することをお勧めします。INotifyPropertyChangedDependencyObject

于 2013-03-04T15:44:59.573 に答える