DataTemplate的绑定为目标提供了不正确/未设置/空值

时间:2018-11-14 09:30:05

标签: c# wpf datatemplate

我想将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='&lt;null&gt;'}" />
</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));
    }
}

1 个答案:

答案 0 :(得分:0)

DataContext的{​​{1}}中根元素的ContentTemplateContentControl的{​​{1}}。将ContentControl属性绑定到您的Content

Content

还必须将DataContext本身(或父窗口)的<ContentControl Content="{Binding Dctx}" ContentTemplate="{Binding DataTemplate}"/> 设置在某个地方,并向DataContext添加一些可视元素:

ContentControl