以下代码是解释我的问题的示例。
我有一个绑定文本框。当我单击按钮时,执行一个功能。 (在这种情况下,它是 for loop )。
现在我想要,文本框更新了 i 变量的内容。 ( public void MyAction())
所以,我制作了一个帖子,但这不起作用。
为什么?
提前致谢
XAML代码
<TextBox Text ="{Binding MyValue}" HorizontalAlignment="Left" Height="47" Margin="4,4,4,4" VerticalAlignment="Top" Width="342"/>
<Button Command="{Binding ClickCommand}" Content="Run" Margin="114,69,283,216"/>
C#代码
class Vm_Main : ViewModelBase
{
public string _MyValue { get; set; } //String in my XAML
public string MyValue
{
get { return _MyValue; }
set
{
_MyValue = value;
base.OnPropertyChanged("MyValue");
}
}
private bool _canExecute=true;
private ICommand _clickCommand;
public ICommand ClickCommand
{
get
{
return _clickCommand ?? (_clickCommand = new CommandHandler(() => MyAction(), _canExecute));
}
}
public Vm_Main()
{
MyValue = "Hallo"; //Default value
}
public void MyAction() // This is the function where I want update the TextBox in Binding
{
Worker workerObject = new Worker();
Thread workerThread = new Thread(workerObject.DoWork);
workerThread.Start();
for (int i = 1; i <= 10; i++)
{
MyValue = i.ToString();
workerObject.Value = MyValue;
Thread.Sleep(500);
}
workerObject.RequestStop();
workerThread.Join();
MessageBox.Show("End");
}
}
// The THREAD
public class Worker : ViewModelBase
{
// This method will be called when the thread is started.
public string _Value { get; set; }
public string Value
{
get { return _Value; }
set
{
_Value = value;
base.OnPropertyChanged("Value");
}
}
public void DoWork()
{
while (!_shouldStop)
{
Console.WriteLine("Value is..." + _Value);
}
Console.WriteLine("End.");
}
public void RequestStop()
{
_shouldStop = true;
}
// Volatile is used as hint to the compiler that this data
// member will be accessed by multiple threads.
private volatile bool _shouldStop;
}
Class ViewModelBase和Class Command
public abstract class ViewModelBase : INotifyPropertyChanged
{
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string strPropertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(strPropertyName));
}
#endregion
#region Messages and Progressbar
private string _errorMessage;
public string ErrorMessage
{
get { return _errorMessage; }
set
{
if (_errorMessage == value) return;
_errorMessage = value;
OnPropertyChanged("ErrorMessage");
}
}
private string _errorTooltip;
public string ErrorTooltip
{
get { return _errorTooltip; }
set
{
if (_errorTooltip == value) return;
_errorTooltip = value;
this.OnPropertyChanged("ErrorTooltip");
}
}
private string _statusMessage;
public string StatusMessage
{
get { return _statusMessage; }
set
{
if (_statusMessage == value) return;
_statusMessage = value;
//pulizia dei messaggi di errore
ErrorMessage = string.Empty;
ErrorTooltip = string.Empty;
OnPropertyChanged("StatusMessage");
}
}
protected void ClearMessage()
{
ErrorMessage = string.Empty;
StatusMessage = string.Empty;
}
private int _currentProgress;
public int CurrentProgress
{
get { return _currentProgress; }
set
{
_currentProgress = value;
OnPropertyChanged("CurrentProgress");
}
}
#endregion
protected ViewModelBase()
{
}
}
public class CommandHandler : ICommand
{
private Action _action;
private bool _canExecute;
public CommandHandler(Action action, bool canExecute)
{
_action = action;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_action();
}
}
答案 0 :(得分:0)
所以我认为你必须解决问题。
首先使用async await
模式。
就是这样 - 不阻止你的UI线程。
public async Task<object> MyAsyncMethod()
{
return await Task.Run<object>(() =>
{
return null;
});
}
或ICommand
只是:
public async void MyAsyncMethod()
{
await Task.Run(() =>
{
});
}
第二是您可能希望在处理异步时更新UI。例如,这是更新进度的常见问题。您可以使用SynchronizationContext
解决此问题。
public interface IUpdateProgess
{
void SendMessage(string val);
}
public async Task<object> MyAsyncMethod(IUpdateProgess progress)
{
//UI thread
SynchronizationContext context = SynchronizationContext.Current;
return await Task.Run<object>(() =>
{
//other thread
if (context != null && progress != null)
{
context.Post(new SendOrPostCallback((o) =>
{
progress.SendMessage("Progress");
}), null);
}
return null;
});
}
你可以使用这显然不仅仅是更新进度 - 我想你明白了。