私はテキストブロックを持っています:
_<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
}
_
しかし、まだ機能していません
プロパティが変更されたことをビューに通知するには、ViewModelオーダーにINotifyPropertyChanged
を実装する必要があります。
MSDNページへのリンクは次のとおりです。 System.ComponentModel.INotifyPropertyChanged
注意すべき最も重要なことは、プロパティセッターでPropertyChanged
イベントを発生させる必要があるということです。
デフォルトではTextblockのバインディングモードは一方向であるため、バインディングモードを二方向に追加します。
<TextBlock HorizontalAlignment="Left" Name="StatusText" Margin="0,20" TextWrapping="Wrap" Text="{Binding StatusText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
... Status ...
</TextBlock>
また、もちろん、目的のためにINotifyPropertyChangedを実装する必要があります。実装方法については this link を参照してください。
DataModelを使用する場合、モデルが初期ロードで完全であることを確認する必要があります。したがって、this.DataContext = mainViewModelとmainViewModelの一部がロードされていない(= null)場合、これらをバインドすることはできません。例、私はそのモデル内にオブジェクトプログラムを持っています。 TextBlockのTextをModel.Program.Nameにバインドします。 Programオブジェクトは初期ロード時に接続されないため、その後は通知を送信できないため、ロードされたオブジェクトに再バインドする必要があります。
ビューモデルはINotifyPropertyChanged
を実装する必要があり、プロパティの1つが変更されるたびに(つまり、セッターで)上げる必要があります。
これがないと、WPFにはプロパティが変更されたことを知る方法がありません。
私はこの問題を抱えていましたが、これが私が間違っていたことです...
注:INotifyPropertyChangedが正しくコーディングされていました。
私の見解では、私は持っていた
<SomeView.DataContext>
<SomeViewModel/>
<SomeView.DataContext/>
...そして、これはVM(バインドされる/を指すインスタンスを作成する)のコンストラクターを呼び出します。
別のクラス(私のプログラムのメインウィンドウのViewModelコード)では、ViewModelのインスタンスも作成していました。
private SomeAstractBaseViewModel someViewModel = new SomeViewModel();
private SomeAstractBaseViewModel someOtherViewModel = new SomeOtherViewModel();
それらは両方ともスーパークラスから継承され、メインウィンドウのセクションに異なるビューを表示するインスタンス間を行き来していました-私の意図どおりです。
それをどのように結び付けるかは別の質問ですが、問題のあるxamlを削除すると(この回答の上部に)以前にViewModelの別の「未使用」インスタンスをインスタンス化していた場合、ViewはINotifyPropertyChangedメカニズムに従って更新されます。