2010-10-18 88 views
1

我有一個綁定到文本塊的依賴項屬性。根據依賴項屬性,如果值更改,它將反映文本塊中的值。資產中的數據來自實時設備。現在,只要有數據傳入,它就會傳播到依賴項屬性,並將到達文本塊。但現在我有問題,客戶想要如果相同的值來了5次,然後改變文本框的背景顏色。依賴項屬性的問題

但我無法收到更改通知。此時,我們很難改變設計。

你們可以請我建議我一些解決方法,並通過依賴項屬性接收所有通知的價值是相同或不同的方式嗎?

+0

您可以分享您所說的綁定的代碼嗎? – Ragepotato 2010-10-18 21:47:59

回答

0

我不確定你要做什麼,但它聽起來像你想跟蹤來自feed的實時值是「新鮮」還是「陳舊」。如果是這樣,INotifyPropertyChanged(依賴屬性背後的力量)可能不會讓你開心,因爲它將完全依賴於該接口的實現,以確定在SAMPLE ISKEN與什麼時候被告知是否會告訴你什麼時候SAMPLE已經改變(它們不是相同的概念)。

根據您的控制力此,我建議你實現你的ViewModel裏面的「陳舊」追蹤(您使用的MVVM,對吧?)

喜歡的東西:

Model.cs :

using System; 
using System.Windows.Threading; 

namespace WpfApplication1 
{ 
    public class Model 
    { 
    private readonly double[] _data = new[] { 2.3, 2.4, 2.5, 2.4, 2.1, 2.1, 2.1, 2.1, 2.0, 2.1, 2.0, 2.1, 2.2, 2.2, 2.2, 2.2, 2.2, 2.4 }; 
    private readonly DispatcherTimer _timer = new DispatcherTimer(); 
    private int _nextSample; 


    public Model() 
    { 
     _timer.Interval = new TimeSpan(0, 0, 0, 1); 
     _timer.Tick += _timer_Tick; 
     _timer.Start(); 
    } 

    public event EventHandler<SampleTakenEventArgs> SampleTaken; 

    private void _timer_Tick(object sender, EventArgs e) 
    { 
     if (SampleTaken != null) 
     { 
     SampleTaken(this, new SampleTakenEventArgs { SampleValue = _data[_nextSample] }); 
     } 
     _nextSample = (++_nextSample%_data.Length); 
    } 
    } 
} 

View.xaml:

<Window x:Class="WpfApplication1.View" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
     <TextBlock Text="{Binding Sample}"/> 
     <TextBlock Text="{Binding StaleCount}"/> 
    </StackPanel> 
</Window> 

View.xaml.cs:

using System.Windows; 

namespace WpfApplication1 
{ 
    public partial class View : Window 
    { 
    public View() 
    { 
     InitializeComponent(); 
     DataContext = new ViewModel(); 
    } 
    } 
} 

ViewModel.cs:

using System.ComponentModel; 

namespace WpfApplication1 
{ 
    public class ViewModel : INotifyPropertyChanged 
    { 
    private readonly Model _model; 
    private double _sample; 
    private int _staleCount; 

    public ViewModel() 
    { 
     _model = new Model(); 
     _model.SampleTaken += _model_SampleTaken; 
    } 

    public double Sample 
    { 
     get { return _sample; } 
     set 
     { 
     _sample = value; 
     OnPropertyChanged("Sample"); 
     } 
    } 

    public int StaleCount 
    { 
     get { return _staleCount; } 
     set 
     { 
     _staleCount = value; 
     OnPropertyChanged("StaleCount"); 
     } 
    } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 

    private void _model_SampleTaken(object sender, SampleTakenEventArgs e) 
    { 
     if (e.SampleValue == Sample) 
     { 
     StaleCount++; 
     } 
     else 
     { 
     StaleCount = 0; 
     } 
     Sample = e.SampleValue; 
    } 

    protected void OnPropertyChanged(string propertyName) 
    { 
     var propertyChanged = PropertyChanged; 
     if (propertyChanged != null) 
     { 
     propertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
    } 
} 
0

警告:這是基於上述問題的破解,這是不理想的設計,但要做到的OP的目標。

你可以滑動您的當前綁定一個IMultiValueConverter,做這樣的事情在XAML ...

<TextBlock Name="TextBlock"> 
    <TextBlock.Background> 
     <MultiBinding Converter="{StaticResource MyConverter}"> 
      <Binding Path="ViewModelProperty"></Binding> 
      <Binding ElementName="TextBlock"></Binding> 
     </MultiBinding> 
    </TextBlock.Background> 
    <TextBlock.Text> 
     <MultiBinding Converter="{StaticResource MyConverter}"> 
      <Binding Path="ViewModelProperty"></Binding> 
      <Binding ElementName="TextBlock"></Binding> 
     </MultiBinding> 
    </TextBlock.Text> 
</TextBlock> 

然後在IMultiValueConverter樣本會...

public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
{ 
    String text = (String)values[0]; 
    TextBlock reference = (TextBlock)values[1]; 

    if (targetType == typeof(String)) 
     return text; 
    else if (targetType == typeof(Brush)) 
    { 
     int count = 0; 
     if (reference.Tag == null) 
      reference.Tag = count; 

     count = (int)reference.Tag; 
     if (++count == 5) 
      return Brushes.Red; 
     else 
      return Brushes.White; 
    } 
    else 
     throw new NotSupportedException(); 
} 

我正在做的是利用你現有的財產,並將其實質性地超載,使你可以將TextBlock.Background財產綁定到ViewModel上已有的財產。請注意在MultiBinding中傳遞TextBlock實例的用法。

與此有關的警告是,如果您的設計正在通過實例移動計數將是不正確的,整個解決方案將有缺陷......不知道......在最初的問題沒有足夠的信息。再次,這是一個黑客攻擊,如果你有更多的權限進行更改,有很多更好的方法來做到這一點。

+0

您的代碼不起作用。如果您從轉換器返回畫筆,則會將文本框的文本設置爲畫筆,然後該畫筆將顯示「System.Drawing.SolidColorbrush」,作爲畫筆的.ToString()。 *絕對*不是原來的要求。 – 2010-10-19 22:49:30

+0

@Dan targetType正在被檢查...如果它是一個字符串,這將是TextBox.Text屬性,它將立即返回文本,如果targetType是Brush,這將是另一個綁定它將返回的Brush ... – 2010-10-19 22:58:14

+0

* *正在返回*畫筆將設置文本框控件的文本爲畫筆。我懷疑你的意圖是將文本框控件的背景設置爲畫筆,然後從轉換器中返回原始字符串 - 但是無論如何,這是一個非常不好用的轉換器。 – 2010-10-19 23:37:00

0

你可以改變DependencyProperty的實現嗎?機會是你可以使用INotifyPropertyChanged作爲一個屬性實現它,如果你可以這樣做,你將能夠實現你需要的計數器邏輯。

從一個DependencyProperty回調不火的時候,價值不會改變,因此,如果您不能改變的實現,那麼,就需要在其他地方鉤碼...

+0

任何理由這被投票下來? – 2010-10-19 23:37:33

0

感謝爲了應對......我知道這是違揹我們理想的設計......但是因爲這已經與我們大部分的部分一起工作,最近客戶改變了需求,因爲想要打印這個值以及顏色也。

所以我有一種方法來解決它在屬性元數據中使用強制回調而不是propertychnage事件。

已解決我的問題。現在我正在爲我的單一控件執行此操作,並且需要此功能,現在我也能夠獲得常量值。

再次感謝