我有一個綁定到文本塊的依賴項屬性。根據依賴項屬性,如果值更改,它將反映文本塊中的值。資產中的數據來自實時設備。現在,只要有數據傳入,它就會傳播到依賴項屬性,並將到達文本塊。但現在我有問題,客戶想要如果相同的值來了5次,然後改變文本框的背景顏色。依賴項屬性的問題
但我無法收到更改通知。此時,我們很難改變設計。
你們可以請我建議我一些解決方法,並通過依賴項屬性接收所有通知的價值是相同或不同的方式嗎?
我有一個綁定到文本塊的依賴項屬性。根據依賴項屬性,如果值更改,它將反映文本塊中的值。資產中的數據來自實時設備。現在,只要有數據傳入,它就會傳播到依賴項屬性,並將到達文本塊。但現在我有問題,客戶想要如果相同的值來了5次,然後改變文本框的背景顏色。依賴項屬性的問題
但我無法收到更改通知。此時,我們很難改變設計。
你們可以請我建議我一些解決方法,並通過依賴項屬性接收所有通知的價值是相同或不同的方式嗎?
我不確定你要做什麼,但它聽起來像你想跟蹤來自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));
}
}
}
}
警告:這是基於上述問題的破解,這是不理想的設計,但要做到的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
實例的用法。
與此有關的警告是,如果您的設計正在通過實例移動計數將是不正確的,整個解決方案將有缺陷......不知道......在最初的問題沒有足夠的信息。再次,這是一個黑客攻擊,如果你有更多的權限進行更改,有很多更好的方法來做到這一點。
您的代碼不起作用。如果您從轉換器返回畫筆,則會將文本框的文本設置爲畫筆,然後該畫筆將顯示「System.Drawing.SolidColorbrush」,作爲畫筆的.ToString()。 *絕對*不是原來的要求。 – 2010-10-19 22:49:30
@Dan targetType正在被檢查...如果它是一個字符串,這將是TextBox.Text屬性,它將立即返回文本,如果targetType是Brush,這將是另一個綁定它將返回的Brush ... – 2010-10-19 22:58:14
* *正在返回*畫筆將設置文本框控件的文本爲畫筆。我懷疑你的意圖是將文本框控件的背景設置爲畫筆,然後從轉換器中返回原始字符串 - 但是無論如何,這是一個非常不好用的轉換器。 – 2010-10-19 23:37:00
你可以改變DependencyProperty的實現嗎?機會是你可以使用INotifyPropertyChanged
作爲一個屬性實現它,如果你可以這樣做,你將能夠實現你需要的計數器邏輯。
從一個DependencyProperty回調不火的時候,價值不會改變,因此,如果您不能改變的實現,那麼,就需要在其他地方鉤碼...
任何理由這被投票下來? – 2010-10-19 23:37:33
感謝爲了應對......我知道這是違揹我們理想的設計......但是因爲這已經與我們大部分的部分一起工作,最近客戶改變了需求,因爲想要打印這個值以及顏色也。
所以我有一種方法來解決它在屬性元數據中使用強制回調而不是propertychnage事件。
已解決我的問題。現在我正在爲我的單一控件執行此操作,並且需要此功能,現在我也能夠獲得常量值。
再次感謝
您可以分享您所說的綁定的代碼嗎? – Ragepotato 2010-10-18 21:47:59