C# WPF:在DataTemplate中绑定DependencyProperty。未激发PropertyChangedCallback

C# WPF:在DataTemplate中绑定DependencyProperty。未激发PropertyChangedCallback,c#,wpf,binding,C#,Wpf,Binding,今天我的处境真的很艰难。由于缺乏WPF方面的经验,我无法理解。我开发了从类生成GUI的小框架(WinForms\WPF\HTML)。为此,我需要动态创建元素 我有带有DependencyProperty的自定义UserControl public partial class ObjectPicker : UserControl { private ViewModel _vm; public ObjectPicker() {

今天我的处境真的很艰难。由于缺乏WPF方面的经验,我无法理解。我开发了从类生成GUI的小框架(WinForms\WPF\HTML)。为此,我需要动态创建元素

我有带有DependencyProperty的自定义UserControl

public partial class ObjectPicker : UserControl
    {
        private ViewModel _vm;
        public ObjectPicker()
        {
            InitializeComponent();
        }

        public object ObjectValue
        {
            get { return GetValue(ObjectValueProperty); }
            set { SetValue(ObjectValueProperty, value); }
        }

        public static DependencyProperty ObjectValueProperty =
            DependencyProperty.Register(
                "ObjectValue",
                typeof(object),
                typeof(ObjectPicker),
                new FrameworkPropertyMetadata(
                    new PropertyMetadata(new object(), OnObjectChangeNotify, CoerceValueCallback), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        private static void OnObjectChangeNotify(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var sender = d as ObjectPicker;
            sender.OnObjectValueChange(d, e);
        }

        public void OnObjectValueChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            this.ObjectValue = e.NewValue;
        }
    }
我有CustomBoundColumn,在这里我重写了GenerateElement方法(其中BindingObject-wrapper具有2个属性值和PropName)。然后我像这样绑定对象,然后它就不工作了

        var content = new ContentControl();
        content.ContentTemplate = (DataTemplate)cell.FindResource(TemplateName);
        var propName = ((Binding)Binding).Path.Path;
        BindingObject bo = new BindingObject(propName, dataItem);
        content.SetValue(ContentControl.ContentProperty, bo);
        return content;
数据模板(例如,我放置了另外两个工作完美的模板):

当它起作用时

我不知道解决这个问题需要什么额外的信息。如果你需要更多,请留下评论,我再加上

更新1:添加BindingObject类

public class BindingObject : INotifyPropertyChanged
{
    private object _value;
    private PropertyDescriptor _pd;
    private MethodInfo _method;

    public BindingObject(string propName, object value)
    {
        _method = value.GetType().GetMethods().FirstOrDefault(x => x.Name == "OnPropertyChanged");
        if (!(value is INotifyPropertyChanged) || _method == null) throw new Exception("Invalid value");
        _value = value;
        _pd = TypeDescriptor.GetProperties(_value.GetType())[propName];

        (_value as INotifyPropertyChanged).PropertyChanged += (o, e) =>
        {
            OnPropertyChanged(nameof(Value));
            OnPropertyChanged(_pd.Name);
        };
    }

    public string PropName
    {
        get { return _pd.Name; }
    }

    public object Value
    {
        get
        {
            return _pd.GetValue(_value);
        }
        set
        {
            _pd.SetValue(_value, value);

        }
    }

    private void RaisePropertyChanged()
    {
        _method.Invoke(_value, new[] { nameof(Value) });
        _method.Invoke(_value, new[] { _pd.Name });
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
UPDATE2:dataItem的实现示例

public class DataItem
{
      public virtual string Value1 { get; set; } // This type of property work fine and binding 
      public virtual int Value2 { get; set; } // This type of property work fine and binding 
      public virtual DateTime Value3 { get; set; } // This type of property work fine and binding 
      public virtual ExampleComplexObject Object { get; set; } // This type not working

}

public class ExampleComplexObject
{
      public virtual int Value1 { get; set; }
      public virtual string Value2 { get; set; }
}

然后,在运行时需要创建对象类型传递给工厂,在工厂中使用INotifyPropertyChanged实现从传递的类型创建代理对象。

我不确定是否理解此处的确切问题,但您可以尝试将ContentControl的Content属性设置为数据对象:

var content = new ContentControl();
content.ContentTemplate = (DataTemplate)cell.FindResource(TemplateName);
content.SetValue(ContentControl.ContentProperty, dataItem);
return content;

然后,您应该能够使用
{Binding Value}

绑定到DataTemplate中的Value属性。我澄清一下BindingObject这是一个对象包装器,它实现了INotifyPropertyChange接口。BindingObject类型具有属性值,我需要绑定该属性值。我可以将这个类添加到起始文章中,以获得更多的理解。这里的数据项是主对象的行。ObjectPickerDataTemplate—具有主对象的复杂类型属性的列。如何定义dataItem类以及ObjectPicker UserControl与此问题的关系如何?您正在GenerateElement方法中创建ContentControl,是吗?dataItem是来自GenerateElement方法参数的变量(受保护的覆盖FrameworkElement GenerateElement(DataGridCell,object dataItem)dataItem这里是SourceItems的对象)。然后dataItem的属性是一个复杂类型,然后我将ObjectPicker组件放在一个单元格中((DataTemplate)cell.FindResource(TemplateName);)我知道“dataItem”参数的来源,但如何定义源对象?ObjectPicker控件的XAML标记是什么样子的?如何从ObjectPicker控件设置source属性的值?请参阅main post。我更新了它。我在组件上没有任何XAML代码,我认为第一步是绑定到自定义属性。这是错误吗?
public class DataItem
{
      public virtual string Value1 { get; set; } // This type of property work fine and binding 
      public virtual int Value2 { get; set; } // This type of property work fine and binding 
      public virtual DateTime Value3 { get; set; } // This type of property work fine and binding 
      public virtual ExampleComplexObject Object { get; set; } // This type not working

}

public class ExampleComplexObject
{
      public virtual int Value1 { get; set; }
      public virtual string Value2 { get; set; }
}
var content = new ContentControl();
content.ContentTemplate = (DataTemplate)cell.FindResource(TemplateName);
content.SetValue(ContentControl.ContentProperty, dataItem);
return content;