2017-04-12 32 views
0

我有一個WPF應用程序,其中我使用轉換器作爲布爾值,以便在指定的時間範圍內顯示時間時將某些文本變爲紅色。時間每3秒更新一次。當有人被標記爲休息時間並且他們休息15分鐘以上時,數據網格中顯示的文本應該變爲紅色。在這種情況下,什麼也沒有發生,我找不到問題。需要WPF轉換器無法工作的幫助

轉換器:

public class BreakRangeToBooleanConverterTime : IValueConverter 
    { 
     public static readonly TimeSpan _toCompare = new TimeSpan(00, 15, 00); 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      if (!(value is TimeSpan)) 
       return DependencyProperty.UnsetValue; 
      return (TimeSpan)value > _toCompare; 
     }  

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      throw new Exception("To Long On Break"); 
     }   
    } 

XAML代碼:

<MultiDataTrigger.Conditions> 
    <Condition Binding="{Binding AuxReasons}" Value="Break"/> 
    <Condition Binding="{Binding Time, RelativeSource={RelativeSource Self}, Converter={StaticResource breakconvtime}}" Value="True"/>         
</MultiDataTrigger.Conditions> 
<Setter Property="Foreground" Value="Red"/> 
<Setter Property="Background" Value="SkyBlue"/> 
</MultiDataTrigger> 
+0

你有沒有定義的資源''BreakRangeToBooleanConverterTime用鑰匙'breakconvtime'? –

+0

是的定義。對不起,我忘了把它包含在我的代碼中。代碼編譯沒有錯誤。 – firehotguitar88

+0

@ firehotguitar88,調試它。在Convert方法中設置一個斷點以確認它是否調用(或不),並且它接收並返回正確(或不正確)的值。另外,如果'時間'是視圖模型的屬性'RelativeSource = {RelativeSource Self}'是不需要的。 – ASh

回答

0

我不知道在哪裏如何綁定,但在這裏沒有必要也許RelativeSource

我下面的作品(我用Prism):

<Window x:Class="TimeBasedTrigger.Views.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:conv="clr-namespace:TimeBasedTrigger.Converters" 
    xmlns:prism="http://prismlibrary.com/" 
    Title="{Binding Title}" 
    Width="525" 
    Height="350" 
    prism:ViewModelLocator.AutoWireViewModel="True"> 
<Window.Resources> 
    <conv:BreakRangeToBooleanConverterTime x:Key="breakconvtime" /> 
    <Style x:Key="TimeoutStyle" TargetType="{x:Type TextBlock}"> 
     <Style.Triggers> 
      <MultiDataTrigger> 
       <MultiDataTrigger.Conditions> 
        <!--<Condition Binding="{Binding AuxReasons}" Value="Break" />--> 
        <Condition Binding="{Binding Time, Converter={StaticResource breakconvtime}}" Value="True" /> 
       </MultiDataTrigger.Conditions> 
       <Setter Property="Foreground" Value="Red" /> 
       <Setter Property="Background" Value="SkyBlue" /> 
      </MultiDataTrigger> 
     </Style.Triggers> 
    </Style> 
</Window.Resources> 
<StackPanel> 
    <StackPanel Orientation="Horizontal"> 
     <Label Content="Time: " /> 
     <TextBlock MinWidth="100" 
        Margin="5,0,10,0" 
        Text="{Binding Time, UpdateSourceTrigger=PropertyChanged}" 
        Style="{StaticResource TimeoutStyle}"/> 
     <Button Command="{Binding StartTimerCommand}" Content="Start" /> 
     <Button Command="{Binding StopTimerCommand}" Content="Stop" /> 
    </StackPanel> 
</StackPanel> 
</Window> 

視圖模型:

public class MainWindowViewModel : BindableBase 
{ 
    CancellationTokenSource _cts = new CancellationTokenSource(); 
    public MainWindowViewModel() 
    { 
     Time = new TimeSpan(); 
    } 

    #region Properties 

    private string _title = "Prism Unity Application"; 
    public string Title 
    { 
     get { return _title; } 
     set { SetProperty(ref _title, value); } 
    } 

    private TimeSpan _time; 
    public TimeSpan Time 
    { 
     get { return _time; } 
     set { SetProperty(ref _time, value); } 
    } 

    private bool _isRunning; 
    public bool IsRunning 
    { 
     get { return _isRunning; } 
     set { SetProperty(ref _isRunning, value); } 
    } 
    #endregion // Properties 

    #region Commands 

    public DelegateCommand StartTimerCommand => new DelegateCommand(StartTimer); 

    private async void StartTimer() 
    { 
     await RepeatActionEvery(() => UpdateTimer(), TimeSpan.FromSeconds(1), _cts.Token); 
    } 

    public DelegateCommand StopTimerCommand => new DelegateCommand(StopTimer); 

    private void StopTimer() 
    { 
     _cts.Cancel(); 
     Time = new TimeSpan(); 
     _cts = new CancellationTokenSource(); 
    } 

    #endregion // Commands 

    #region Private Methods 

    private void UpdateTimer() 
    { 
     var timeIncrement = TimeSpan.FromSeconds(1); 
     Time = Time.Add(timeIncrement); 
    } 

    #endregion // Private Methods 

    #region Helpers 

    public static async Task RepeatActionEvery(Action action, TimeSpan interval, CancellationToken cancellationToken) 
    { 
     while (true) 
     { 
      action(); 
      Task task = Task.Delay(interval, cancellationToken); 

      try { await task; } 
      catch (TaskCanceledException) { return; } 
     } 
    } 

    #endregion // Helpers 
} 
+0

我不知道棱鏡是什麼。我對WPF很陌生,並沒有在我的應用程序中使用MVVM風格,我開始相信這是我的錯誤。您的視圖模型上面我不明白它的目的。如果我正確地閱讀它,那麼您是如何增加計時器正確計數的時間?在我的情況下,我測量的時間是從接口報告的,所以我需要查看已經綁定到數據網格中的字段的時間跨度,以確定轉換器是否激活。 – firehotguitar88

+0

您已綁定到XAML中的Time屬性,因此此屬性必須引發'PropertyChanged'才能使綁定生效。你的代碼是什麼?這是在一個代碼隱藏文件? – mechanic

+0

我目前沒有這樣做。所以它可能是我的問題。我從來沒有必須綁定屬性更改值,我認爲XAML一直引用轉換器。 – firehotguitar88