2010-12-29 14 views
2

私はカウントダウンタイマーを実装しています。私はDispatcherTimerを使って、時間を示しているTextBlockを持っています。WPF:XAMLのプロパティ値としてコードから変数を使用する方法は?

TextBlockFontSizeプロパティのアニメーションを作成したいと思います。私は、その値がタイマーが午後9時を示す時点で300ptに増加したい。したがって、アプリケーションが実行されてもそれが増え続けるたびにFontSizeは8ptで始まり、リアルタイムが9pmに達するとFontSizeは300ptになるはずです。

私はそれをどのように描写しましたか:アプリケーションが実行されると、その瞬間から午後9時になるまでの秒数が計算されます。結果は変数timeToGetTo9pmによって格納されます。私が直面している問題は、XAMLでアニメーションを作成するときに、DurationプロパティにtimeToGetTo9pmを設定する方法がわからないことです。

アイデア?また、私のアプローチが愚かで混乱している場合は、より良いものをお勧めします。ありがとう。

委任本体:

private void dispatcherTimer_Tick(object sender, EventArgs e) 
{ 
    DateTime currentTime; 
    double timeToNewYearInMiliseconds; 

    currentTime = DateTime.Now; 

    //targetTime is a DateTime object set elsewhere, 
    //It represents the 9pm mentioned in the question body 
    if (DateTime.Compare(targetTime, currentTime) > 0) 
    { 
     timeToNewYearInMiliseconds = targetTime.Subtract(currentTime).TotalMilliseconds; 
     percent = 100/timeToNewYearInMiliseconds; 
     PercentageComplete = percent; 
    } 
} 
+0

chibacityは間違いな方法を提供してきました。私の場合を解決しても、XAMLのプロパティ値としてコードから変数を使用する方法を学びたいと思います。 – Boris

+0

@Borris xamlのコードビハインドのプロパティを使用するサンプルコードを使用して回答を更新しました。 –

答えて

3

あなたのViewModel \コードビハインドで「TimerFontSize」プロパティを持っており、それにテキストボックスののFontSizeを結合しないのはなぜ。あなたのタイマーティックのよう

FontSize="{Binding TimerFontSize, Mode=OneWay}" 

、フォントサイズを再計算すると「TimerFontSize」プロパティを設定します。 'TimerFontSize'にINotifyPropertyChangedを実装している場合、TextBoxバインディングは自動的にフォントのサイズを変更して変更します。

このパターンでは、タイマーとデータバインディングを使用してアニメーションを駆動します。

更新

私はあなたが再何を意味するかを参照してください。視覚表現とデータ表現を分離する。私の提案は簡単な方法です。公開されたプロパティに経過時間またはカウントダウン値を設定し、ValueConverterを使用してFontSizeを取得することで、このプロパティをクリーンアップすることができます。これにより、データとビューの概念が分離されます。

コードビハインドでプロパティを公開するコード例を示します。前に説明したバインディングを使用してそれを接続してください。理想的には、コードビハインドではなく、ViewModelクラスにリファクタリングするのが理想です。

public partial class TimerView : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    private double _fontSize; 
    private readonly DispatcherTimer _timer; 

    public TimerView() 
    { 
     InitializeComponent(); 

     _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) }; 
     _timer.Tick += delegate {/*calculate font size and set TimerFontSize*/}; 
     _timer.Start(); 
    } 

    public double TimerFontSize 
    { 
     get { return _fontSize; } 
     private set 
     { 
      _fontSize = value; 
      InvokePropertyChanged("TimerFontSize"); 
     } 
    } 

    private void InvokePropertyChanged(string name) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(name)); 
     } 
    }   
} 

アップデート2

および結合ValueConverter、例えば:

を使用ビュー表現からモデル表現を分離する:

FontSize="{Binding PercentageComplete, 
        Mode=OneWay, 
        Converter={StaticResource percentToFontSizeConverter}}" 

ValueConverter:

public class PercentToFontSizeValueConverter : IValueConverter 
{ 
    private static double _DpiX; 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     double percent = (double)value; 
     double fontPointSize = (percent * 300); 
     double fontDpiSize = (fontPointSize * (DpiX/72d)); 
     return fontDpiSize; 
    } 

    private static double DpiX 
    { 
     get 
     { 
      if (_DpiX == 0) 
      { 
       Matrix m = PresentationSource. 
          FromVisual(Application.Current.MainWindow). 
          CompositionTarget. 
          TransformToDevice; 

       _DpiX = (m.M11 * 96d); 
      } 

      return _DpiX; 
     } 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

コードビハインド:

public partial class TimerView : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    private double _percent; 
    private readonly DispatcherTimer _timer; 

    public TimerView() 
    { 
     InitializeComponent(); 

     _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) }; 
     _timer.Tick += delegate{/*Calulate perecent and set PercentageComplete */}; 
     _timer.Start(); 
    } 

    public double PercentageComplete 
    { 
     get { return _percent; } 
     private set 
     { 
      _percent = value; 
      InvokePropertyChanged("PercentageComplete"); 
     } 
    } 

    private void InvokePropertyChanged(string name) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(name)); 
     } 
    } 
} 
+0

答えをありがとう。何もうまくいけない場合は、私があなたが示唆したようにします。私の目標は、一般的なアニメーションやスタイルから時間を変更するロジックを分離することでした。いずれにしても、XAMLのプロパティ値としてコードから変数を使用する方法はまだ分かりません。 – Boris

+0

@Borris xamlのコードビハインドのプロパティを使用するサンプルコードを使用して回答を更新しました。 –

+0

@Borris私は自分のFont Point-to-DPIサイズの計算に間違った方法を使用しました - コードは今更新され、正しいです。 –

関連する問題