0

Rachel Lim のブログに従って、ビジネス ロジックの検証を実装しました。次のようにIsValidプロパティにバインドされたビューにトリガーを配置することを決定するまで、すべてが順調に進んでいました。

<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) がある場合、トリガーが再評価するように通知されず、アイテムのフォーカス可能なプロパティが true のままになることです。

GetValidationError() が値を返す前に NotifyPropertyChanged("IsValid") を配置しようとしましたが、この方法でスタックオーバーフロー例外が発生します。

#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
4

2 に答える 2

3

もちろん、スタックオーバーフローが発生します。あなたがするとき:

NotifyPropertyChanged("IsValid")

IsValid の値を再評価するように WPF インフラストラクチャに強制します。これは、IsValid ゲッターを呼び出すことによって行われ、GetValidationError が再度呼び出されます。

これを処理するにはいくつかの方法があります。おそらく、IsValid の最後の値を保持するプライベート メンバー変数を作成し、NotifyPropertyChanged を呼び出す前に、現在の値を古い値と比較します。

もう 1 つの方法は、検証済みのプロパティの 1 つが変更されたときにのみ NotifyPropertyChanged("IsValid") を呼び出すことです (つまり、これらの各プロパティのセッターで)。これがIsValid の変更を引き起こす可能性があるためです。

于 2012-07-25T14:06:53.303 に答える
0
        private bool _isValid;
    public bool IsValid
    {
        get
        {
            string.IsNullOrWhiteSpace(GetValidationError())
            return _isValid;
        }
        set
        {
            _isValid = value;
            NotifyPropertyChanged("IsValid");
        }
    }

    public string GetValidationError()
    {
        string error = null;

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

これが役立つことを願っています。

于 2012-07-25T14:07:49.263 に答える