我有一个文本块:
<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()
返回类似“完成工作”的字符串等。来自该函数的值被赋予this.StatusText
,但TextBlock的文本属性不会更改,并且仍显示占位符“...状态。 ..“
我知道这样的问题 - &gt; CLICK&lt; ---但在阅读完之后我仍然无法找到解决方案
@Update
根据你的建议我更新了我的代码,现在我有了这个:
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
}
但它仍无效
答案 0 :(得分:22)
您需要在ViewModel顺序中实现INotifyPropertyChanged
,以通知View该属性已更改。
以下是指向MSDN页面的链接:System.ComponentModel.INotifyPropertyChanged
最重要的是要注意在属性设置器中引发PropertyChanged
事件。
答案 1 :(得分:10)
双向添加绑定模式,因为默认情况下Textblock的绑定模式是单向
<TextBlock HorizontalAlignment="Left" Name="StatusText" Margin="0,20" TextWrapping="Wrap" Text="{Binding StatusText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
... Status ...
</TextBlock>
当然,您需要为此目的实施 INotifyPropertyChanged ,请参阅this link了解如何实施。
答案 2 :(得分:3)
使用DataModels时,您必须确保模型在初始加载时完成。因此,如果你这样做:this.DataContext = mainViewModel和你的mainViewModel的某些部分没有加载(= null),那么你无法绑定它们。例如,我在该模型中有一个Model对象程序。我将TextBlock的Text绑定到Model.Program.Name。 Program对象在初始加载时未连接,因此您必须重新绑定到加载的对象,否则无法发送通知。
答案 3 :(得分:2)
您的视图模型需要实现INotifyPropertyChanged
,并且每次您的某个属性更改时(即在setter中)都需要提升它。
没有它,WPF无法知道该属性已经发生变化。
答案 4 :(得分:0)
我遇到了这个问题,这就是我做错了......
注意:我已正确编码INotifyPropertyChanged。
在我看来,我有
<SomeView.DataContext>
<SomeViewModel/>
<SomeView.DataContext/>
...这会调用VM的构造函数(创建指向/要绑定的实例)。
在另一个类中(在我的程序的主窗口的ViewModel代码中)我也在实例化ViewModel,即:
private SomeAstractBaseViewModel someViewModel = new SomeViewModel();
private SomeAstractBaseViewModel someOtherViewModel = new SomeOtherViewModel();
它们都是从超类继承的,我在主窗口的一个部分中显示不同视图的实例之间来回切换 - 按照我的意图。
如何连接所有内容是另一个问题,但是当我删除之前实例化另一个&#34的有问题的 xaml (在此答案的顶部)未使用&#34; ViewModel的实例,View将根据 INotifyPropertyChanged 机制进行更新。
答案 5 :(得分:0)
在我的情况下,一个UserControl
嵌套在一个View
中,当我尝试Binding
到UserControl
内的某个属性时,框架在ViewModel
(不存在)。为了解决这个问题,我必须指定ElementName
。
MyControl.xaml:
<UserControl
...
x:Name="MyUserControl">
...
<Label Content="{Binding MyProperty, ElementName=MyUserControl}"
...
MyControl.xaml.cs:
public partial class MyControl: UserControl, INotifyPropertyChanged
{
...
private string _myProperty = "";
public string MyProperty
{
get => _myProperty ;
set
{
if (value == _myProperty ) return;
_myProperty = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
...