Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# DependencyProperty、UserControl、回调触发一次_C#_Wpf - Fatal编程技术网

C# DependencyProperty、UserControl、回调触发一次

C# DependencyProperty、UserControl、回调触发一次,c#,wpf,C#,Wpf,我在usercontrol中使用treeview控件。Usercontrol用于主窗口(仅用于测试)。主窗口的DataContext是我的ViewModel。 在usercontrolcodebhind中,我设置了一些dependencProperty,并且一切都正常工作,eccept属性不会触发回调。 在ViewModel中有一个ObservableCollection树。MyObject包含ObservableCollection Leafs的属性。这是我用来填充树视图的树结构 如果我将Tr

我在usercontrol中使用treeview控件。Usercontrol用于主窗口(仅用于测试)。主窗口的DataContext是我的ViewModel。 在usercontrolcodebhind中,我设置了一些dependencProperty,并且一切都正常工作,eccept属性不会触发回调。 在ViewModel中有一个ObservableCollection树。MyObject包含ObservableCollection Leafs的属性。这是我用来填充树视图的树结构

如果我将Tree属性传递给usercontrol(usign一个dependencProperty源),它可以正常工作。我的意思是,如果我在ViewModel中更改树中的元素,Source将触发通知,TreeView将更新。 如果我将Tree.Leafs.elementAt(0)CurrentTree传递给usercontrol(使用另一个DependencyProperty根),则只有在加载usercontrol时才会触发一次通知。如果我更改CurrentTree,ViewModel中的通知会起作用,但UserControl中的RootChanged()不会引发。我不明白为什么

代码如下: 主窗口

<DockPanel>
    <controls:TreeView Root="{Binding CurrentTree, Mode=TwoWay, diag:PresentationTraceSources.TraceLevel=High}">            
    </controls:TreeView>
</DockPanel>
用户控制代码隐藏

 public static readonly DependencyProperty RootProperty = DependencyProperty.Register("Root", typeof(MyObject), typeof(TreeView), new FrameworkPropertyMetadata(new PropertyChangedCallback(RootChanged)));
private static void RootChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    ((TreeView)d).Root= (MyObject)e.NewValue;
}

public MyObject Root
{
    get
    {
        return (MyObject)GetValue(RootProperty);
    }
    set
    {
        SetValue(RootProperty, value);
    }
}
TreeView(用户控制)xaml

所以,我不明白为什么DependencyPropertyCallback被触发一次。

问题解决了

代码有点复杂,然后发布代码。 结构如下:

1个具有类MyViewModel的类库项目

2带有“MyTreeView”的用户控件库项目

3用于测试1和2的Wpf项目。MainWindow datacontext是来自1的MyViewModel

主要问题不是DP

在类库项目中,我使用了从所有其他类继承的BaseNotify类。我的视图模型也是。 从MyViewModel中删除BaseNotify并直接继承INotifyPropertyChanged,现在一切正常! 我不知道为什么,但它起作用了

BaseNotify类:

public class BaseNotify : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
问题解决了

代码有点复杂,然后发布代码。 结构如下:

1个具有类MyViewModel的类库项目

2带有“MyTreeView”的用户控件库项目

3用于测试1和2的Wpf项目。MainWindow datacontext是来自1的MyViewModel

主要问题不是DP

在类库项目中,我使用了从所有其他类继承的BaseNotify类。我的视图模型也是。 从MyViewModel中删除BaseNotify并直接继承INotifyPropertyChanged,现在一切正常! 我不知道为什么,但它起作用了

BaseNotify类:

public class BaseNotify : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

实际上你不需要回电话。您正在尝试第二次设置属性值-它已经为您设置好了。对根属性进行双向绑定似乎也没有意义。控件是否设置过该属性本身?另一个注意事项是,将一个属性作为另一个属性的支持“字段”看起来也很奇怪。将
private BsonTree currentTree{get;set;}
更改为
private BsonTree currentTree。虽然很明显,但NotifyPropertyChanged()
使用了
CallerMemberNameAttribute
?所以TreeView只是为了让我们困惑?真的,改变它,特别是当它只是用于这篇文章。还请向我们展示一些实际更改CurrentTree属性的代码。不,当属性由绑定(和其他一些源)设置时,不会调用setter。WPF直接调用SetValue(RootProperty,…)。实际上,您不需要回调。您正在尝试第二次设置属性值-它已经为您设置好了。对根属性进行双向绑定似乎也没有意义。控件是否设置过该属性本身?另一个注意事项是,将一个属性作为另一个属性的支持“字段”看起来也很奇怪。将
private BsonTree currentTree{get;set;}
更改为
private BsonTree currentTree。虽然很明显,但NotifyPropertyChanged()
使用了
CallerMemberNameAttribute
?所以TreeView只是为了让我们困惑?真的,改变它,特别是当它只是用于这篇文章。还请向我们展示一些实际更改CurrentTree属性的代码。不,当属性由绑定(和其他一些源)设置时,不会调用setter。WPF直接调用SetValue(RootProperty,…)。
System.Windows.Data Warning: 67 : BindingExpression (hash=14200498): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=14200498): Found data context element: TreeView (hash=49044892) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=14200498): Activate with root item ViewModel (hash=49218346)
System.Windows.Data Warning: 108 : BindingExpression (hash=14200498):   At level 0 - for ViewModel.CurrentTree found accessor ReflectPropertyDescriptor(CurrentTree)
System.Windows.Data Warning: 104 : BindingExpression (hash=14200498): Replace item at level 0 with ViewModel (hash=49218346), using accessor ReflectPropertyDescriptor(CurrentTree)
System.Windows.Data Warning: 101 : BindingExpression (hash=14200498): GetValue at level 0 from ViewModel (hash=49218346) using ReflectPropertyDescriptor(CurrentTree): MyObject (hash=52380055)
System.Windows.Data Warning: 80 : BindingExpression (hash=14200498): TransferValue - got raw value MyObject (hash=52380055)
System.Windows.Data Warning: 89 : BindingExpression (hash=14200498): TransferValue - using final value MyObject (hash=52380055)
public class BaseNotify : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}