我想将DataContext
从动态创建的DataTemplate
向上传播,并以ContentControl
托管,如下所示:
var myFactory = new FrameworkElementFactory(controlTypeToDisplay);//= typeof(MyControl)
var dctxBinding = new Binding
{
Path = new PropertyPath("DataContext.Dctx"),
Mode = BindingMode.OneWayToSource,
RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(ContentControl), 1)
};
myFactory.SetBinding(FrameworkElement.DataContextProperty, dctxBinding);
return new DataTemplate() { VisualTree = myFactory };
但是,即使在null
的构造函数中设置了DataContext,这种绑定的结果也是MyControl
。 MyControl的DataContext绝对不会进一步设置为null,在Dctx
的setter之前调用构造方法。如何修复绑定,以使MyControl
的DataContext和Dctx
属性始终保持同步?
此问题的完整示例(如果正常工作,应显示两个“ FooBar” TextBlocks):
//MyControl.xaml
<Grid>
<TextBlock Text="{Binding}"/>
</Grid>
//MyControl.xaml.cs
public MyControl()
{
InitializeComponent();
DataContext = "FooBar";
this.DataContextChanged += MyControl_DataContextChanged;
}
private void MyControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
MessageBox.Show("An unexpected change");
}
//MainWindow.xaml
<StackPanel>
<ContentControl ContentTemplate="{Binding DataTemplate}"/>
<TextBlock Text="{Binding Dctx, TargetNullValue='<null>'}" />
</StackPanel>
//MainWindow.xaml.cs
public partial class MainWindow : Window, INotifyPropertyChanged
{
private Type controlTypeToDisplay = typeof(MyControl);
public DataTemplate DataTemplate
{ get {/*see first listing*/ } }
private object _dctx;
public object Dctx
{
get { return _dctx; }
set { _dctx = value; RaisePropertyChanged(); }
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged([CallerMemberName]string caller = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(caller));
}
}
答案 0 :(得分:0)
DataContext
的{{1}}中根元素的ContentTemplate
是ContentControl
的{{1}}。将ContentControl
属性绑定到您的Content
:
Content
还必须将DataContext
本身(或父窗口)的<ContentControl Content="{Binding Dctx}" ContentTemplate="{Binding DataTemplate}"/>
设置在某个地方,并向DataContext
添加一些可视元素:
ContentControl