web-dev-qa-db-ja.com

ビューを更新しないWPFバインディング

私はテキストブロックを持っています:

_<TextBlock HorizontalAlignment="Left" Name="StatusText" Margin="0,20" TextWrapping="Wrap" Text="{Binding StatusText}">
            ... Status ...
</TextBlock>
_

分離コード:

_public StatusPage()
{
    InitializeComponent();
    this.DataContext = new StatusPageViewModel(this);
}
_

およびviewModelで:

_private string _statusText;
/// <summary>
/// Status text
/// </summary>
public string StatusText
{
    get { return _statusText; }
    set { _statusText = value; }
}
_

およびviewModelの関数内:

_string statusText = Status.GetStatusText();
this.StatusText = statusText;
_

GetStatusText()は、「Work done」などの文字列を返します。その関数の値は_this.StatusText_に割り当てられますが、TextBlockのtextプロパティは変更されず、プレースホルダー "... Status .. 」

私はこのような質問を知っています-> [〜#〜] click [〜#〜] <---しかしこれを読んだ後、私はまだ解決策を見つけることができません

@更新

あなたの提案の後、私は私のコードを更新し、今私はこれを持っています:

_public string StatusText
{
    get 
    {
        return _statusText;
    }
    set 
    {
        _statusText = value; 
        RaisePropertyChanged("StatusText");
    }
}
_

およびviewModelの宣言:

_ public class StatusPageViewModel : ObservableObject, INavigable
_

ここで:

ObservableObjectクラスは次のとおりです。

_public abstract class ObservableObject : INotifyPropertyChanged
{
    #region INotifyPropertyChanged Members

    /// <summary>
    /// Raises the PropertyChange event for the property specified
    /// </summary>
    /// <param name="propertyName">Property name to update. Is case-sensitive.</param>
    public virtual void RaisePropertyChanged(string propertyName)
    {
        OnPropertyChanged(propertyName);
    }

    /// <summary>
    /// Raised when a property on this object has a new value.
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Raises this object's PropertyChanged event.
    /// </summary>
    /// <param name="propertyName">The property that has a new value.</param>
    protected virtual void OnPropertyChanged(string propertyName)
    {

        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }

    #endregion // INotifyPropertyChanged Members
}
_

しかし、まだ機能していません

17
szpic

プロパティが変更されたことをビューに通知するには、ViewModelオーダーにINotifyPropertyChangedを実装する必要があります。

MSDNページへのリンクは次のとおりです。 System.ComponentModel.INotifyPropertyChanged

注意すべき最も重要なことは、プロパティセッターでPropertyChangedイベントを発生させる必要があるということです。

23
toadflakz

デフォルトではTextblockのバインディングモードは一方向であるため、バインディングモードを二方向に追加します。

<TextBlock HorizontalAlignment="Left" Name="StatusText" Margin="0,20" TextWrapping="Wrap" Text="{Binding StatusText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
            ... Status ...
</TextBlock>

また、もちろん、目的のためにINotifyPropertyChangedを実装する必要があります。実装方法については this link を参照してください。

10
Mayur Dhingra

DataModelを使用する場合、モデルが初期ロードで完全であることを確認する必要があります。したがって、this.DataContext = mainViewModelとmainViewModelの一部がロードされていない(= null)場合、これらをバインドすることはできません。例、私はそのモデル内にオブジェクトプログラムを持っています。 TextBlockのTextをModel.Program.Nameにバインドします。 Programオブジェクトは初期ロード時に接続されないため、その後は通知を送信できないため、ロードされたオブジェクトに再バインドする必要があります。

3

ビューモデルはINotifyPropertyChangedを実装する必要があり、プロパティの1つが変更されるたびに(つまり、セッターで)上げる必要があります。

これがないと、WPFにはプロパティが変更されたことを知る方法がありません。

2
GazTheDestroyer

私はこの問題を抱えていましたが、これが私が間違っていたことです...

注:INotifyPropertyChangedが正しくコーディングされていました。


私の見解では、私は持っていた

<SomeView.DataContext>
    <SomeViewModel/>
<SomeView.DataContext/>

...そして、これはVM(バインドされる/を指すインスタンスを作成する)のコンストラクターを呼び出します。

別のクラス(私のプログラムのメインウィンドウのViewModelコード)では、ViewModelのインスタンスも作成していました。

private SomeAstractBaseViewModel someViewModel = new SomeViewModel();
private SomeAstractBaseViewModel someOtherViewModel = new SomeOtherViewModel(); 

それらは両方ともスーパークラスから継承され、メインウィンドウのセクションに異なるビューを表示するインスタンス間を行き来していました-私の意図どおりです。

それをどのように結び付けるかは別の質問ですが、問題のあるxamlを削除すると(この回答の上部に)以前にViewModelの別の「未使用」インスタンスをインスタンス化していた場合、ViewはINotifyPropertyChangedメカニズムに従って更新されます。

0
JohnG79