【发布时间】:2018-06-15 06:07:52
【问题描述】:
@grek40 回答
我已经在我的项目中实现了INotifyPropertyChanged,其他一切都运行良好,但是对于这个变量绑定文本块,它只在主窗口加载事件上更新一次。
我可能只是在某个地方遗漏了一些小细节,请帮忙!
MainWindow.xaml
<TextBlock HorizontalAlignment="Left" Margin="317,161,0,0"
TextWrapping="Wrap" Text="{Binding ish.IsDoingWork, Mode=OneWay,
UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top"/>
<Button Command="{Binding hksVm.HentKundeStatus}" Content="Invoke"
HorizontalAlignment="Left" Margin="704,139,0,0" VerticalAlignment="Top"
Width="75"/>
MainWindow.xaml.cs(设置数据上下文)
public MainWindow()
{
if (!ValidationHandler.GrantAccess().Equals(3))
{
InitializeComponent();
DataContext = new
{
hksVm = new HentKundeStatusVm(),
ish = new InvocationServiceHandler()
};
}
else
{
Close();
}
}
ViewModel.cs
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Input;
namespace MyNamespace
{
public class HentKundeStatusVm : IViewModel
{
private ICommand _hentKundeStatus;
private readonly InvocationServiceHandler _invocationServiceHandler = new InvocationServiceHandler();
public ICommand HentKundeStatus => HentKundeStatusCommand();
public ICommand HentKundeStatusCommand()
{
if (ValidationHandler.GrantAccess() < 2)
{
return _hentKundeStatus ?? (_hentKundeStatus = new RelayCommand(param =>
ElapsedTime = _invocationServiceHandler.ExecuteAndTimeAction(
() =>
{
//web API kaldes asynkront - husk: using System.Net.Http;
using (var client = new HttpClient().GetAsync("API-url"))
{
client.Result.Content.ReadAsStringAsync();
}
}, AntalKald)));
}
return null;
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string property)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
}
}
InvocationServiceHandler.cs
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading.Tasks;
using App005_WebServiceTestingTool_Domain.Annotations;
namespace App005_WebServiceTestingTool_Domain.Handlers
{
public class InvocationServiceHandler : INotifyPropertyChanged
{
// This works on the main_window load event and set the textblock in the view
private string _isDoingWork = "Currently not working";
public string IsDoingWork
{
get => _isDoingWork;
set
{
_isDoingWork = value;
NotifyPropertyChanged(nameof(IsDoingWork));
}
}
/// <summary>
/// Method that invokes action parameter x times in multiple threads (parallel) and returns the elapsed time
/// </summary>
/// <param name="action"></param>
/// <param name="antalKald"></param>
/// <returns></returns>
public string ExecuteAndTimeAction(Action action, string antalKald)
{
// Here is set the bound variable, and if I debug I can see it getting set to Working...
IsDoingWork = "Working...";
var sw = new Stopwatch();
sw.Start();
for (int i = 0; i < Convert.ToInt32(antalKald); i++)
{
action.Invoke();
}
sw.Stop();
// Here I am resetting the variable and again in debug I can see it change, but nothing happens in the view
IsDoingWork = "";
return $"Elapsed time: {sw.Elapsed}";
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
public void NotifyPropertyChanged(string property)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
}
}
【问题讨论】:
-
只有在释放 UI 线程时才会更新 UI。您在执行操作时似乎一直阻塞 UI 线程?
-
在动作运行后文本块不会更新吗?
-
你如何运行
ExecuteAndTimeAction?请完整显示minimal reproducible example(更多详细信息)和最小化(更少不需要的东西,例如 BindingMode=OneWay, UpdateSourceTrigger=PropertyChanged的组合,它永远不会触发 OneWay 的更新) -
@grek40 - OneWay 是 OneWayToTarget 所以这部分看起来不错。
标签: c# wpf inotifypropertychanged