[英]WPF MVVM textBox Text Binding
我剛剛開始使用MVVM,如果我做了一些非常愚蠢的事情,那么道歉。 我試着寫一個非常簡單的測試來看看我是否能記住一切,而對於我的生活,我不明白為什么它不起作用。
在我看來,我有一個textBox,其text屬性綁定到ViewModel中的值。 然后當按下按鈕時,應該更改值並更新textBox。
我可以看到值確實改變了(我在buttom press命令中添加了MessageBox.Show()行)但是textBox沒有更新。
我認為這意味着我沒有正確實現INotifyPropertyChanged
事件,但我無法看到我的錯誤。
有人能指出我正確的方向嗎?
這是代碼:
視圖
<Window x:Class="Mvvm.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
<TextBox Height="40" Width="200" Text="{Binding helloWorld.Message, UpdateSourceTrigger=PropertyChanged}"/>
<Button Command="{Binding UpdateTimeCommand}">Update</Button>
</StackPanel>
</Window>
在視圖后面
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel.MainWindowViewModel();
}
}
視圖模型
namespace Mvvm.ViewModel
{
internal class MainWindowViewModel
{
private HelloWorld _helloWorld;
/// <summary>
/// Creates a new instance of the ViewModel Class
/// </summary>
public MainWindowViewModel()
{
_helloWorld = new HelloWorld("The time is " + DateTime.Now.ToString("HH:mm:ss"));
UpdateTimeCommand = new Commands.UpdateTimeCommand(this);
}
/// <summary>
/// Gets the HellowWorld instance
/// </summary>
public HelloWorld helloWorld
{
get
{
return _helloWorld;
}
set
{
_helloWorld = value;
}
}
/// <summary>
/// Updates the time shown in the helloWorld
/// </summary>
public void UpdateTime()
{
helloWorld = new HelloWorld("The time is " + DateTime.Now.ToString("HH:mm:ss"));
}
public ICommand UpdateTimeCommand
{
get;
private set;
}
}
模型
namespace Mvvm.Model
{
class HelloWorld : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public HelloWorld(string helloWorldMessage)
{
Message = "Hello World! " + helloWorldMessage;
}
private string _Message;
public string Message
{
get
{
return _Message;
}
set
{
_Message = value;
OnPropertyChanged("Message");
}
}
private void OnPropertyChanged(string p)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(p));
}
}
}
}
命令
namespace Mvvm.Commands
{
internal class UpdateTimeCommand : ICommand
{
private ViewModel.MainWindowViewModel _viewModel;
public UpdateTimeCommand(ViewModel.MainWindowViewModel viewModel)
{
_viewModel = viewModel;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
_viewModel.UpdateTime();
}
}
}
對不起,這么長的帖子,這是我的錯誤發布的地方,但我看了很久,我不知道我做錯了什么
謝謝!
您遇到的問題是您正在更改錯誤的屬性。 您正在更改MainWindowViewModel.HelloWorld
屬性,而不是更改HelloWorld.Message
屬性。 如果更改此行,您的代碼將正常工作:
public void UpdateTime()
{
helloWorld = new HelloWorld("The time is " + DateTime.Now.ToString("HH:mm:ss"));
}
對於這個
public void UpdateTime()
{
helloWorld.Message = "The time is " + DateTime.Now.ToString("HH:mm:ss");
}
如果要保留原始代碼,則需要為ViewModel實現INotifyPropertyChanged,並在更改helloWorld
對象時引發事件。
希望這可以幫助
我認為您需要在ViewModel上實現PropertyChanged通知。 您正在UpdateTime方法中創建一個新的HelloWorld,但UI不知道它。
我有一個ViewModel基類,我從中派生出所有的ViewModel。 它實現了INotifyPropertyChanged,並引用了我的中繼命令類和其他一些常見的東西。 我建議始終在ViewModel上實現INotifyPropertyChanged。 ViewModel用於向UI公開數據,並且無法在沒有該接口的情況下更改數據。
我認為您的ViewModel也需要實現INotifyPropertyChanged,或者您可以在調用InitializeComponents()之前設置DataContext,如果這樣做,您應該將代碼更改為不創建每個更新的新實例,如Agustin Meriles所說。
在您的VM(HelloWorld類)中,您需要使用您的模型
所以,你的類看起來像:
using System.ComponentModel; namespace WpfApplication1 { public sealed class TextVM : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private TextInfo _info; public TextVM() { _info = new TextInfo(); } public string MyText { get { return _info.MyText; } set { _info.MyText = value; OnPropertyChanged("MyText"); } } private void OnPropertyChanged(string p) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(p)); } } } } using System; namespace WpfApplication1 { public sealed class TextInfo { public TextInfo() { MyText = String.Empty; } public string MyText { get; set; } } }
嵌入在ICommands中
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.