本文介绍了在哪里提出NotifyPropertyChanged?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚根据Rachel Lim的博客.一切运行良好,直到我决定在视图中将触发器绑定到 IsValid 属性,如下所示:

I just implemented my business logic validation according to Rachel Lim's blog.Everything was running great until I decided to put a trigger in my view bound to the IsValid property like this:

<ListBox ItemsSource="{Binding EdgedBoards}" SelectedItem="{Binding SelEdgedBoard, Mode=TwoWay}" DisplayMemberPath="Name"> 
                    <ListBox.ItemContainerStyle>
                        <Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}">
                            <Setter Property="Focusable" Value="True" />
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Path=IsValid}" Value="False">
                                    <Setter Property="Focusable" Value="False" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ListBox.ItemContainerStyle>
                </ListBox>

问题在于,当绑定的项目出现错误(SelEdgedBoard.IsValid == false)时,不会通知触发器重新评估,并且该项目将其focusable属性保持为true.

The problem is that when the bound item has an error (SelEdgedBoard.IsValid == false) the trigger is not notified to reevaluate and the item keeps its focusable property to true.

我已经尝试在GetValidationError()返回其值之前放置一个NotifyPropertyChanged("IsValid"),但是这样我会得到一个stackoverflow异常:

I've already tried to put a NotifyPropertyChanged("IsValid") before the GetValidationError() returns its value, but this way I get a stackoverflow exception:

#region IsValid Property

    public bool IsValid
    {
        get
        {
            return string.IsNullOrWhiteSpace(GetValidationError());
        }
    }

    public string GetValidationError()
    {
        string error = null;

        if (ValidatedProperties != null)
        {
            foreach (string s in ValidatedProperties)
            {
                error = GetValidationError(s);
                if (!string.IsNullOrWhiteSpace(error))
                {
                    break; 
                }
            }
        }

        NotifyPropertyChanged("IsValid");
        return error;
    }

    #endregion

推荐答案

当然,它会导致堆栈溢出.当您这样做时:

Of course it causes a stack overflow. When you do:

NotifyPropertyChanged("IsValid")

您强制WPF基础结构重新评估IsValid的值.它是通过调用IsValid getter来实现的,后者又再次调用GetValidationError!

You force the WPF infrastructure to reevaluate the value of IsValid. It does this by calling the IsValid getter, which, in turn, calls GetValidationError again!

有几种方法可以解决此问题.我可能会创建一个私有成员变量来保存IsValid的最后一个值,然后在调用NotifyPropertyChanged之前将当前值与旧值进行比较.

There are several ways you can handle this. I would probably create a private member variable to hold the last value of IsValid and then compare the current value to the old value before calling NotifyPropertyChanged.

另一种方法可能是,当您验证的属性之一发生更改时(因此在每个属性的设置器中),仅调用NotifyPropertyChanged("IsValid"),因为这可能导致 发生更改. IsValid.

Another way might be to only call NotifyPropertyChanged("IsValid") when one of your validated properties changes (so in the setter of each of those properties) as this is what might cause a change in IsValid.

这篇关于在哪里提出NotifyPropertyChanged?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 02:24