4

DependencyPropertyを持つUserControlがあります。データバインディング式を使用して、ホストウィンドウで値を設定します。ただし、期待どおりに機能しません。

ユーザーコントロールのコードビハインドからのスニペット:

public class ViewBase : UserControl
{
    public static readonly DependencyProperty ViewModelProperty
        = DependencyProperty.Register(
            "ViewModel", typeof(ViewModelBase), typeof(ViewBase));

    public ViewModelBase ViewModel
    {
        get { return GetValue(ViewModelProperty) as ViewModelBase; }
        set
        {
            SetValue(ViewModelProperty, value);
        }
    }
}

XAMLから(注:CasingListViewはViewBaseから継承します):

<CasingEditor:CasingListView x:Name="_casingListView"
                             ViewModel="{Binding CasingListViewModel}" />

何が起こるかは何もありません。具体的には、setterが呼び出されることはなく、プロパティはnullのままです。ソースプロパティCasingListViewModelに値があることはわかっています。これは、別のプロパティ(DataContext)にバインドしようとしたため、正常に機能しました。

依存関係プロパティはデータバインドできると思いました。私が間違っている?

4

1 に答える 1

6

時々起こることですが、問題は私たちが思っていたものとはまったく異なることが判明しました。

セッターが呼ばれることはなかったと言いました。それは本当です。上記のコードは、わかりやすくするために少しトリミングされています。残念ながら、SetValueの呼び出しに続いて、セッターのステートメントも削除しました。そのステートメントは、次のような値をDataContextに割り当てました。

public ViewModelBase ViewModel
{
    get { return GetValue(ViewModelProperty) as ViewModelBase; }
    set
    {
        SetValue(ViewModelProperty, value);
        DataContext = value;
    }
}

この優れた記事から学んだように、プロパティがデータバインディングを介して設定されると、実際にはセッターはバイパスされます。代わりに、フレームワークはDependencyObjectに対して直接機能します。そのため、プロパティは実際に設定されましたが、(前述のように)セッターが呼び出されることはなく、その結果、DataContextはnullのままで、何も機能しませんでした。

だから:最初に私は答えられない質問をしたことを深くお詫びします。第二に、それを補う方法として、私は非常に重要なアドバイスを伝えることができます:

GetValue()とSetValue()以外は、常に呼び出されるとは限らないため、プロパティgetter/setter内に配置しないでください。

編集:後で、私はこのアプローチに別の問題も発見しました。このようにDataContextを設定すると、最初にバインディングをサポートする元のデータコンテキストが実際に失われます。その結果、プロパティはすぐにnullにリセットされます。したがって、全体として、全体として良いアプローチではありません。

于 2009-10-14T14:53:48.933 に答える