我有一个绑定到文本块的依赖项属性。根据依赖项属性,如果值更改,它将反映文本块中的值。资产中的数据来自实时设备。现在,只要有数据传入,它就会传播到依赖项属性,并将到达文本块。但现在我有问题,客户想要如果相同的值来了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