实时更新XAML组件可见性 - UWP

时间:2016-12-27 12:31:54

标签: c# xaml uwp caliburn.micro uwp-xaml

我有一个在我的UWP应用程序后台运行的定期线程,我想绑定某些组件'对其执行的可见性。我正在使用caliburn并绑定组件,如下所示:

<TextBox Name="sample" Visibility="{Binding JobStatus}" />

C#:

public string JobStatus
{
    get
    {
        if(SponsorReferralUploadService.IsRunning())
            return "Collapsed";
        else
            return "Visible";
    }
}

这个布尔值来自应用程序的服务层,因此我无法重写/重新设计所有代码并实现INotifyPropertyChanged接口。

当我打开这个页面时,Visibility的{​​{1}}被设置为布尔值是真还是假,我怎样才能以这样的方式对布尔值进行编程:更新后,TextBox属性已更改?

4 个答案:

答案 0 :(得分:2)

您是否尝试过 INotifyPropertyChanged (名称空间System.ComponentModel)事件?

  
    

事件PropertyChangedEventHandler PropertyChanged;

  

答案 1 :(得分:1)

为了澄清,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中。

答案 2 :(得分:0)

public Visibility JobStatus
{
   get
   {
       if(SponsorReferralUploadService.IsRunning())
           return Visibililty.Collapsed;
       else
           return Visibililty.Visible;    
   }
}

如果你确实使用了Caliburn.Micro,那么当NotifyOfPropertyChanged(() => JobStatus);检测到更改时,需要使用SponsorReferralUploadService将INPC合并到框架中。

这里棘手的部分是如果SponsorReferralUploadService是一个定期服务,它是如何得到这个消息的,那么你还需要EventAggregator(可能)的某些内容来让它发布变化并让IHandle根据发布的消息实际更新属性,即实际调用NotifyOfPropertyChanged(() => JobStatus)。将EventAggregator视为一个跨视图模型消息泵,点火并忘记,考虑到这一点,不保证消息传递,通常与viewmodel生命周期有关。

这个getter实际上很大,只需要一行代码和一个内置在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>

当然,关于获取更新的关键仍然在于谁调用或检查属性更改。

答案 3 :(得分:0)

对于小型应用程序,使用 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;
    }
}