实时更新 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 接口。

当我打开这个页面时,TextBoxVisibility 被设置为布尔值是真还是假,我如何以一种方式来编程它,只要布尔值已更新,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;
    }
}