实时更新 XAML 组件可见性 - UWP
Updating XAML component Visibility in real time - UWP
我的 UWP 应用程序后台有一个周期性线程 运行,我想将某些组件的可见性与其执行联系起来。我正在使用 Caliburn 并像这样绑定组件:
<TextBox Name="sample" Visibility="{Binding JobStatus}" />
C#:
public string JobStatus
{
get
{
if(SponsorReferralUploadService.IsRunning())
return "Collapsed";
else
return "Visible";
}
}
此布尔值来自应用程序的服务层,因此我无法 rewrite/redesign 所有代码并实现 INotifyPropertyChanged
接口。
当我打开这个页面时,TextBox
的 Visibility
被设置为布尔值是真还是假,我如何以一种方式来编程它,只要布尔值已更新,Visibility
属性 已更改?
您是否尝试过 INotifyPropertyChanged(命名空间 System.ComponentModel)事件?
event PropertyChangedEventHandler PropertyChanged;
澄清一下,WPF 中的数据绑定不会 不断重新评估。一旦 UI 获得了您的 JobStatus 属性 的值,它就不会再询问了。除非,也就是说,你告诉它。
更常见的方法是在您的 ViewModel 上实现 INotifyPropertyChanged
,然后触发 PropertyChanged 事件。但您也可以通过调用绑定表达式的 UpdateTarget
方法以编程方式强制更新绑定:
sample.GetBindingExpression(TextBlock.VisibilityProperty).UpdateTarget();
如果没有某种事件告诉您何时调用此方法,您将被迫使用计时器重复调用它:
var timer = new System.Windows.Threading.DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1.0);
timer.Tick += timer_Tick;
timer.Start();
...
void timer_Tick(object sender, EventArgs e)
{
sample.GetBindingExpression(TextBlock.VisibilityProperty).UpdateTarget();
}
但是,如果您无论如何都在使用计时器,那么您真的应该考虑是否应该将计时器放在 ViewModel 中并使用它来触发 PropertyChanged 事件。在我看来,这种细节(即轮询服务的适当频率)应该在 ViewModel 而不是 View 中。
public Visibility JobStatus
{
get
{
if(SponsorReferralUploadService.IsRunning())
return Visibililty.Collapsed;
else
return Visibililty.Visible;
}
}
如果您确实在使用 Caliburn.Micro,那么当您的 SponsorReferralUploadService
检测到更改时,需要调用 NotifyOfPropertyChanged(() => JobStatus);
将 INPC 合并到框架中。
这里棘手的部分是,如果 SponsorReferralUploadService
是定期服务,它如何获取此消息,那么您还需要类似于 EventAggregator
(可能)的内容才能发布更改并让 IHandle
根据发布的消息实际进行 属性 更新,即对 NotifyOfPropertyChanged(() => JobStatus)
的实际调用。将 EventAggregator
视为跨视图模型消息泵,即发即弃,考虑到这一点,消息传递没有保证,通常与视图模型生命周期相关。
这个 getter 实际上很大,只需要 1 行代码和一个内置于 BooleanToVisibilityConverter
转换器中的转换器。
public bool JobStatus
{
get{
return SponsorReferralUploadService.IsRunning();
}
}
然后如图所示 Textbox
会变成这样
<TextBox Name="Sample" Visibility="{Binding JobStatus, Convert={StaticResource BoolVis}}" />
<Page.Resources>
<cal:BooleanToVisibilityConverter x:Key="BoolVis" />
</Page.Resources>
当然,关于获取更新的宣传仍然是关于谁调用或检查 属性 更改。
对于小型应用程序使用 mvermef 表示 属性 代码或以其他方式使用它。
对于大型应用程序,请使用此布尔转换器,这将帮助您获得更多属性。
<TextBox Name="sample" Visibility="{Binding JobStatus,Converter={staticResource BooleanToVisibilityConverter}" />
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (bool)value ? Visibility.Visible : Visibility.Collapsed;
}
}
我的 UWP 应用程序后台有一个周期性线程 运行,我想将某些组件的可见性与其执行联系起来。我正在使用 Caliburn 并像这样绑定组件:
<TextBox Name="sample" Visibility="{Binding JobStatus}" />
C#:
public string JobStatus
{
get
{
if(SponsorReferralUploadService.IsRunning())
return "Collapsed";
else
return "Visible";
}
}
此布尔值来自应用程序的服务层,因此我无法 rewrite/redesign 所有代码并实现 INotifyPropertyChanged
接口。
当我打开这个页面时,TextBox
的 Visibility
被设置为布尔值是真还是假,我如何以一种方式来编程它,只要布尔值已更新,Visibility
属性 已更改?
您是否尝试过 INotifyPropertyChanged(命名空间 System.ComponentModel)事件?
event PropertyChangedEventHandler PropertyChanged;
澄清一下,WPF 中的数据绑定不会 不断重新评估。一旦 UI 获得了您的 JobStatus 属性 的值,它就不会再询问了。除非,也就是说,你告诉它。
更常见的方法是在您的 ViewModel 上实现 INotifyPropertyChanged
,然后触发 PropertyChanged 事件。但您也可以通过调用绑定表达式的 UpdateTarget
方法以编程方式强制更新绑定:
sample.GetBindingExpression(TextBlock.VisibilityProperty).UpdateTarget();
如果没有某种事件告诉您何时调用此方法,您将被迫使用计时器重复调用它:
var timer = new System.Windows.Threading.DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1.0);
timer.Tick += timer_Tick;
timer.Start();
...
void timer_Tick(object sender, EventArgs e)
{
sample.GetBindingExpression(TextBlock.VisibilityProperty).UpdateTarget();
}
但是,如果您无论如何都在使用计时器,那么您真的应该考虑是否应该将计时器放在 ViewModel 中并使用它来触发 PropertyChanged 事件。在我看来,这种细节(即轮询服务的适当频率)应该在 ViewModel 而不是 View 中。
public Visibility JobStatus
{
get
{
if(SponsorReferralUploadService.IsRunning())
return Visibililty.Collapsed;
else
return Visibililty.Visible;
}
}
如果您确实在使用 Caliburn.Micro,那么当您的 SponsorReferralUploadService
检测到更改时,需要调用 NotifyOfPropertyChanged(() => JobStatus);
将 INPC 合并到框架中。
这里棘手的部分是,如果 SponsorReferralUploadService
是定期服务,它如何获取此消息,那么您还需要类似于 EventAggregator
(可能)的内容才能发布更改并让 IHandle
根据发布的消息实际进行 属性 更新,即对 NotifyOfPropertyChanged(() => JobStatus)
的实际调用。将 EventAggregator
视为跨视图模型消息泵,即发即弃,考虑到这一点,消息传递没有保证,通常与视图模型生命周期相关。
这个 getter 实际上很大,只需要 1 行代码和一个内置于 BooleanToVisibilityConverter
转换器中的转换器。
public bool JobStatus
{
get{
return SponsorReferralUploadService.IsRunning();
}
}
然后如图所示 Textbox
会变成这样
<TextBox Name="Sample" Visibility="{Binding JobStatus, Convert={StaticResource BoolVis}}" />
<Page.Resources>
<cal:BooleanToVisibilityConverter x:Key="BoolVis" />
</Page.Resources>
当然,关于获取更新的宣传仍然是关于谁调用或检查 属性 更改。
对于小型应用程序使用 mvermef 表示 属性 代码或以其他方式使用它。
对于大型应用程序,请使用此布尔转换器,这将帮助您获得更多属性。
<TextBox Name="sample" Visibility="{Binding JobStatus,Converter={staticResource BooleanToVisibilityConverter}" />
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (bool)value ? Visibility.Visible : Visibility.Collapsed;
}
}