Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.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# WPF数据绑定-中间对象的Getter/Setter未被命中 我的WPF文本框使用一个类实例(称为“SelectedDocument”)作为其数据上下文。此类实现INOtifyPropertyChanged SelectedDocument实例拥有另一个类型为“CellContent”(名为“Description”)的对象,该对象通过属性公开 CellContent还实现INotifyPropertyChanged CellContent类有一个可以绑定到的字符串属性(“TextValue”)_C#_Wpf_Xaml_Data Binding - Fatal编程技术网

C# WPF数据绑定-中间对象的Getter/Setter未被命中 我的WPF文本框使用一个类实例(称为“SelectedDocument”)作为其数据上下文。此类实现INOtifyPropertyChanged SelectedDocument实例拥有另一个类型为“CellContent”(名为“Description”)的对象,该对象通过属性公开 CellContent还实现INotifyPropertyChanged CellContent类有一个可以绑定到的字符串属性(“TextValue”)

C# WPF数据绑定-中间对象的Getter/Setter未被命中 我的WPF文本框使用一个类实例(称为“SelectedDocument”)作为其数据上下文。此类实现INOtifyPropertyChanged SelectedDocument实例拥有另一个类型为“CellContent”(名为“Description”)的对象,该对象通过属性公开 CellContent还实现INotifyPropertyChanged CellContent类有一个可以绑定到的字符串属性(“TextValue”),c#,wpf,xaml,data-binding,C#,Wpf,Xaml,Data Binding,我正在将TextBox的Text属性绑定到该TextValue属性。像这样: <TextBox DataContext="{Binding SelectedDocument}" Text="{Binding Path=Description.TextValue" /> (这个属性在我的代码中更复杂。)然后WPF可以到达实际的CellContent对象内部并获取/设置TextValue 问题:描述属性从未命中。看起来WPF绕过了它,并在Description对象内部创建了到TextV

我正在将TextBox的Text属性绑定到该TextValue属性。像这样:

<TextBox DataContext="{Binding SelectedDocument}" Text="{Binding Path=Description.TextValue" />
(这个属性在我的代码中更复杂。)然后WPF可以到达实际的CellContent对象内部并获取/设置TextValue

问题:描述属性从未命中。看起来WPF绕过了它,并在Description对象内部创建了到TextValue属性的直接连接。我想每次都点击描述getter和setter,这样我就可以在那里执行一些额外的代码


我该怎么做

每次更改
TextValue
属性时,请尝试引发
PropertyChanged
事件进行描述。

如果希望在孩子的属性更改时将文档标记为脏,可以订阅孩子的
PropertyChanged
事件

我假设您当前的文档看起来像这样

public class Doc
{
    public Doc()
    {
        _description = new CellContent();
       // subscribe to changes in child
        _description.PropertyChanged += DescriptionChanged; 
    }

    private void DescriptionChanged(object sender, PropertyChangedEventArgs e)
    {
        Debug.Write($"I'm a dirty dirty document. Property {e.PropertyName} has changed");
    }

    private CellContent _description;
    public CellContent Description
    {
        get
        {
            Debug.Write("I assure you this is called every time a getter of the child properties is called");
            return _description;
        }
        // If you have a setter, don't forget to -= unsubscribe and resubscribe += after changing
    }
}

如果没有一个好消息,就不可能对正在发生的事情做出任何自信的陈述。但WPF不会检索
Description
属性值是非常自然的,除非该属性值实际发生更改。只要所有更改都是
Description.TextValue
,就只会检索
TextValue
属性。考虑到这一点,您需要问一个不同的问题:如何解决导致您误入歧途的更广泛的目标,在这种设计中,您希望在没有理由的情况下检索属性值。因为我们不知道更广泛的目标是什么,我们实际上无法帮助您。到目前为止,我们所能做的只是告诉您框架正在按预期工作,您的预期是有缺陷的。底层设计并没有什么神奇之处:描述过去是一个字符串属性,我曾经直接绑定到它。该Description属性中有一些额外的代码将被执行(每次反馈数据时,文档都被标记为Dirty)。现在,每段数据都不仅仅是一个字符串,因此将所有数据封装到一个新类中并通过旧属性访问该类是有意义的。除了不再被点击之外,获取属性值并不会固有地修改对象(如文档)。“脏”标志通常表示对象已被修改。因此,在代码获取属性值时设置“dirty”标志在最好的情况下是不典型的,在最坏的情况下是完全错误的。最好在属性更改时修改标志。如果您有多层设计,文档本身应该订阅它所依赖的对象中的属性更改通知,并更新其“dirty”标志以响应该通知。让您的业务逻辑依赖于UI逻辑的副作用是错误的。“我希望在数据绑定到达CellContent时,中间的getter和setter会被命中(只是代码路径,忘记NotifyPropertyChanged)——请解释为什么您希望在所有WPF都需要获取属性值的情况下调用setter。嗯,我该怎么做?一切都是通过数据绑定直接从XAML启动的。好吧,基本上是NPras所说的:)谢谢你纵容我上面的愚蠢。我会将此标记为正确,因为。。。好吧,毕竟你应该这样做。
public class Doc
{
    public Doc()
    {
        _description = new CellContent();
       // subscribe to changes in child
        _description.PropertyChanged += DescriptionChanged; 
    }

    private void DescriptionChanged(object sender, PropertyChangedEventArgs e)
    {
        Debug.Write($"I'm a dirty dirty document. Property {e.PropertyName} has changed");
    }

    private CellContent _description;
    public CellContent Description
    {
        get
        {
            Debug.Write("I assure you this is called every time a getter of the child properties is called");
            return _description;
        }
        // If you have a setter, don't forget to -= unsubscribe and resubscribe += after changing
    }
}