7

SongDescriptionというカスタムUserControlがあります。

<UserControl x:Class="DPTestAp.SongDescription" ...>
    <Grid x:Name="LayoutRoot">
        <DockPanel Height="50">
            <TextBlock x:Name="title" Text="{Binding name}" Width="100" Height="30"/>
            <TextBox x:Name="lyrics"/>
        </DockPanel>
    </Grid>
</UserControl>

DependencyPropertyを追加しました:

public partial class SongDescription : UserControl
{
    public static readonly DependencyProperty SongProperty = DependencyProperty.Register("Song", typeof(Song), typeof(SongDescription));

    public Song Song
    {
        get
        {
            return (Song)GetValue(SongProperty);
        }
        set
        {
            SetValue(SongProperty, value);
            updateLyrics()
        }
    }

    private void updateLyrics()
    {
        lyrics.Text = Song.lyrics;
    }

    public SongDescription()
    {
        InitializeComponent();
    }
}

問題は、このSongPropertyに何かをバインドする方法ですか?メインウィンドウでSongDescriptionを次のように使用します。

<local:SongDescription x:Name="songDescription" Song="{Binding DataContext}"/>

TextBoxの歌詞に歌詞を表示させることができません。メインウィンドウで、次のようにDataContextをsongDescriptionに設定しようとしました。

songDescription.DataContext = new Song() { name="Home", lyrics="Hold on, to me as we go" };

または、次のようにウィンドウ自体を表示します。

DataContext = new Song() { name="Home", lyrics="Hold on, to me as we go" };

Songをリソースにして、次のようにSongPropertyにバインドしようとしました。

<Window.Resources>
    <local:Song x:Key="res" name="Home" lyrics="Hold on, to me as we go"/>
</Window.Resources>
<Grid>
    <local:SongDescription x:Name="songDescription" Song="{StaticResource res}"/>
</Grid>

何も役に立たなかった。TextBlockのタイトルは曲名をうまくバインドします。しかし、updateLyrics()メソッドを呼び出させることはできません。(実際には、このメソッドはより複雑なので、名前のようにBindingを使用することはできません)。

ありがとうございました!

4

2 に答える 2

9

うん、それは依存関係プロパティの落とし穴です。アクセサー メソッド (get/set) 内に検証コードを配置することはありませ。これは、依存関係プロパティが WPF によって管理されるテーブルに格納されるためです。これが、依存関係プロパティを登録する必要がある理由です。基本的に、各プロパティに関連付けられた値を格納するためにこのテーブルにエントリを作成し、「GetValue」/「SetValue」を使用すると、このテーブルのエントリを更新します (ちなみにこれは一般に、WPF がデータ バインディングを管理する方法に関連しています)。

ただし、これの結果は、実際のデータに直接アクセスできるため、WPF はプロパティ アクセサーを完全にバイパスできる (そしてそうする) ことです。データに直接アクセスできるのに、アクセサーを使用する必要があるのはなぜですか。代わりに、「PropertyChanged」コールバック関数または検証を行うための WPF 認定メソッドを実装する必要がありますが、アクセサーでは決して実行しないでください

見る:

http://msdn.microsoft.com/en-us/library/ms752914.aspx

于 2013-02-05T15:51:59.643 に答える
2

sircodesalot の回答に加えて、歌詞のテキスト ボックスに縛られることはありません。また、バインド先の曲はクラスであるため、「Path=Song.Lyrics」などのボックスに表示するプロパティのパスを完全に指定する必要があります。

考慮すべきもう 1 つのことは、依存関係プロパティの場合です。モードはデフォルトで一方向になるため、テキストフィールドを編集可能にすることは、変更しない限り意味がありません。

第 3 に、MVVM を使用している場合は、メイン ウィンドウ コンテキストをビュー モデルに設定し、バインド対象の対応する Song プロパティを設定するだけで済みます。

于 2013-02-05T16:16:07.443 に答える