14

WPF で DataContext を定義するには、主に 2 つの方法があるようです。

  • 次のようなコードのいずれかで:

App.xaml.cs ( WPF MVVM Toolkit テンプレートから取得):

public partial class App : Application
{
    private void OnStartup(object sender, StartupEventArgs e)
    {
        // Create the ViewModel and expose it using the View's DataContext
        MainView mainView = new MainView();
        MainViewModel mainViewModel = new MainViewModel();
        mainViewModel.LoadCustomers("c:\\testdata2\\Customers.xml");
        mainView.DataContext = mainViewModel;
        mainView.Show();
    }
}
  • または、次のような XAML で:

Window1.xaml:

<DockPanel>
    <StackPanel
        HorizontalAlignment="Left"
        DockPanel.Dock="Top"
        Orientation="Horizontal">
        <StackPanel.DataContext>
            <local:CustomerViewModel />
        </StackPanel.DataContext>
        <TextBlock Text="{Binding Path=FirstName}" />
        <TextBlock Text=" " />
        <TextBlock Text="{Binding Path=LastName}" />
    </StackPanel>

    <StackPanel
        HorizontalAlignment="Left"
        VerticalAlignment="top"
        DockPanel.Dock="Top"
        Orientation="Horizontal">
        <ListBox ItemsSource="{Binding Source={StaticResource FileNames}}" />
    </StackPanel>

    <StackPanel
        HorizontalAlignment="Left"
        VerticalAlignment="top"
        DockPanel.Dock="Top"
        Orientation="Horizontal">
        <ComboBox
            ItemsSource="{Binding Source={StaticResource Directories}}"
            SelectedIndex="0" />
    </StackPanel>

    <StackPanel
        HorizontalAlignment="Left"
        VerticalAlignment="top"
        DockPanel.Dock="Top"
        Orientation="Horizontal">
        <StackPanel.DataContext>
            <local:SystemInformationViewModel />
        </StackPanel.DataContext>
        <TextBlock Text="{Binding Path=CurrentTime}" />
    </StackPanel>
</DockPanel>

XAML で DataContext を定義する利点の 1 つは、データが Expression Blend デザイン モードで表示され、 Expression Blend を使用すると、ここに示すようにデータソースからフィールドを選択するなど、GUI 内で多くのことを実行できることです。

バインディングADO.NET オブジェクトを XAML にバインドできないことを読みました(ただし、XAML からバインドできる最小限のラッパーを記述できる理由はわかりません)。

WPF MVVM テンプレートを作成する際に WPF チームがコードで DataContext を定義するのは奇妙です。これにより、レイアウトの重要な部分であることが多いデザイン モードでデータが表示されないため、Expression Blend でビューを編集することがすぐに実行不可能になります。 .

したがって、XAML の代わりにコードで DataContext を設定することには、何らかの利点があるに違いないと考えています。

4

7 に答える 7

16

d:DataContext属性を使用することで、両方の世界を最大限に活用できます(おそらく2009年にはできませんでした) 。まだ準備ができていなければ、そのViewModelLocator狂気は必要ありません:-)

まず、ルート要素に次のXML名前空間が定義されていることを確認してください。

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

次に、xamlの要素に次の属性を追加できます。

d:DataContext="{d:DesignInstance IsDesignTimeCreatable=True, Type=vm:CustomerInsightViewModel}"

xamlコードビハインド:

    public CustomerInsightUserControl()
    {
        InitializeComponent();

        if (!DesignerProperties.IsInDesignTool)
        {
            DataContext = new CustomerInsightViewModel();
        }
    }

次に、ViewModelで:

    public CustomerInsightViewModel()
    {
        if (IsInDesignMode)
        {
            // Create design time data
            Customer = new Customer() {
                FirstName=... 
            }
        }
        else {
            // Create datacontext and load customers
        }
    }

見逃さないでください。さもないIsDesignTimeCreatable=Trueと、Blendはクラスをインスタンス化しません。

于 2010-08-01T05:32:33.110 に答える
6

Expression Blend でデータ オブジェクトをインスタンス化しようとするのは好きではありません。

依存性注入を使用して適切なオブジェクト、サービス、プロバイダー、またはコードを見つけるために使用しているものを挿入できるコードを介して DataContext を設定します。

于 2009-05-14T11:38:36.537 に答える
1

これには、DataObjectProvider を使用して、データが XAML の外部でインスタンス化されているという事実をマスクするという、一種の解決策がある可能性があります。

Blend がプロパティを取得するのに十分な DataContext の型が示されます。

私はまだこれを試していないので、一粒の塩で考えてください。しかし、調査する価値があることは確かです。

于 2009-05-14T12:00:57.763 に答える
1

ここで暗示されているように、ObjectDataProvider を使用して、Unity または他の IOC を使用してオブジェクト ファクトリを確立することもできるはずです...

http://social.msdn.microsoft.com/Forums/en/wpf/thread/1ff9e90e-302e-436e-bab3-ca4bad2b85af

特に...

http://www.codeproject.com/Articles/43806/WPF-Ninject-Dojo-The-Data-Provider.aspx

于 2011-03-31T00:43:10.300 に答える
1

コードビハインドに含めると、ユニティを使用してデータコンテキストを簡単に挿入できます。

于 2009-05-14T11:33:34.427 に答える