2017-10-27 18 views
0

私は再利用可能なUserControlを開発しようとしていますが、バインディングの問題が発生しています。私はそれをテストするための小さなアプリケーションを作成しましたが、それを並べ替えることはできませんでした。WPF UserControlは親DataContextを継承しません

コードは以下のとおりです。私が期待することは、MainWindow.xamlに置いたTestUserControlのインスタンスは、TextBlockのようにDataContextを継承するということです。代わりに、DataContextはnullのようです。 DataContextが渡されない理由はありますか?自動的に設定する必要はありますか?

MainWindow.xaml

<Window x:Class="WpfTestApp.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:WpfTestApp" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel Orientation="Vertical"> 
     <local:TestUserControl TextFromParent="{Binding SomeText}" /> 
     <TextBlock Name="TestTextBlock" Text="{Binding SomeText}" /> 

    </StackPanel> 
</Window> 

MainWindow.xaml.cs

using System.ComponentModel; 
using System.Runtime.CompilerServices; 
using System.Windows; 

namespace WpfTestApp 
{ 
    public partial class MainWindow : Window, INotifyPropertyChanged 
    { 
     private string _someText; 

     public MainWindow() 
     { 
      DataContext = this; 

      InitializeComponent(); 

      SomeText = "New Text!"; 
     } 

     public string SomeText 
     { 
      get { return _someText; } 
      set 
      { 
       _someText = value; 
       NotifyOnPropertyChanged(); 
      } 
     } 
     public event PropertyChangedEventHandler PropertyChanged; 

     protected void NotifyOnPropertyChanged([CallerMemberName] string propertyName = "") 
     { 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

TestUserControl.xaml

<UserControl x:Class="WpfTestApp.TestUserControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:WpfTestApp" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <Grid> 
     <TextBlock Name="TheTextBlock" Text="{Binding TextFromParent}" /> 

    </Grid> 
</UserControl> 

TestUserControl.xaml.cs

プログラムが働いて結合とのTextBlockによって空白続いて、次の実行し、最初のテキストのようになります。 enter image description here

答えて

2

ユーザーコントロールは、実際に、その親要素からのDataContextを継承しています。ただし、DataWindowインスタンスであるため、DataContextにはTextFromParentというプロパティはありません。

UserControlのXAMLのバインドは、現在のDataContextの1つではなく、UserControl自体のプロパティにバインドされていると考えられます。したがって、それは、ソースオブジェクトとして、ユーザーコントロールのインスタンスを使用する必要があります自体にユーザーコントロールのDataContextの設定

<TextBlock Text="{Binding TextFromParent, 
        RelativeSource={RelativeSource AncestorType=UserControl}}" /> 

それのDataContext値をコントロールの親要素から継承されることを防止するため、オプションではありません。

<UserControl ...> 
    <Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"> 
     <TextBlock Text="{Binding TextFromParent}" /> 
    </Grid> 
</UserControl> 

ただし、潜在的に多くのバインディングにRelativeSourceを設定しないようにUserControlのXAMLのルート要素のDataContextのを設定することができ

関連する問題