C# 如何在WPF数据绑定中通知DateTime更改事件?
我有一个WPF应用程序,它使用这样的绑定C# 如何在WPF数据绑定中通知DateTime更改事件?,c#,wpf,datetime,binding,colors,C#,Wpf,Datetime,Binding,Colors,我有一个WPF应用程序,它使用这样的绑定 <DataGridTextColumn Header="BeginDate" Binding="{Binding BeginDate}"> <DataGridTextColumn.CellStyle> <Style TargetType="DataGridCell"> <Setter Property="Background" Value="{Binding BeginD
<DataGridTextColumn Header="BeginDate" Binding="{Binding BeginDate}">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Background" Value="{Binding BeginDate, Converter={StaticResource beginDate} }" />
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
问题是我如何观察每天的日期时间变化?我需要这个颜色转换器动态改变自己的颜色,但当日期时间。现在改变,颜色不会被通知改变
致以最良好的祝愿。
非常感谢。背景颜色取决于日期时间的变化。现在,在您的代码中,绑定到BeginDate将保持不变。因此,您必须通过在ViewModel中触发PropertyChanged事件来发送BeginDate已显式更改的通知。您可以为此使用计时器:
DispatcherTimer _timer = null;
更新
下面的示例是带有计时器的解决方案的概念证明。带有BeginDate的细胞背景每秒会将其颜色从橙色更改为透明。EmployeesListViewModel是带有DataGrid的控件的DataContext。不要忘记为每个EmployeeDetailsViewModel调用StopTimer(),以防止内存泄漏
XAML
C#
公共类EmployeesListViewModel:INotifyPropertyChanged
{
私人可观察收集的员工;
公共雇员列表视图模型()
{
_员工=新的可观察集合();
_Add(newemployeedetailsviewmodel(){BeginDate=DateTime.Now});
_Add(newemployeedetailsviewmodel(){BeginDate=DateTime.Now.AddDays(1)});
}
公开收集雇员
{
获取{return\u employees;}
}
}
公共类EmployeeDetailsViewModel:INotifyPropertyChanged
{
Dispatchermer\u timer=null;
公共雇员详细信息模型()
{
_计时器=新调度程序();
_timer.Interval=TimeSpan.FromSeconds(1);
_timer.Tick+=(s,e)=>{OnPropertyChanged(“BeginDate”);};
_timer.Start();
}
公共无效停止计时器()
{
_timer.Stop();
}
私人日期时间;
公共日期时间开始
{
获取{return\u beginDate;}
设置
{
_beginDate=值;
不动产变更(“开始日期”);
}
}
公共事件属性更改事件处理程序属性更改;
受保护的虚拟void OnPropertyChanged(字符串propertyName)
{
if(this.PropertyChanged!=null)
{
var e=新的PropertyChangedEventArgs(propertyName);
本。财产变更(本,e);
}
}
}
公共类ColorBeginDateConverter:IValueConverter
{
公共对象转换(对象值,类型targetType,
对象参数,CultureInfo(区域性)
{
尝试
{
如果(DateTime.Now.Second%2==0)
返回刷。透明;
其他的
返回刷。橙色;
}
捕获(例外)
{
返回刷。透明;
}
}
公共对象转换回(对象值,类型targetType,
对象参数,CultureInfo(区域性)
{
返回“未执行”;
}
}
背景颜色取决于日期时间的变化。现在,但在代码中,您绑定到的BeginDate将保持不变。因此,您必须通过在ViewModel中触发PropertyChanged事件来发送BeginDate已显式更改的通知。您可以为此使用计时器:
DispatcherTimer _timer = null;
更新
下面的示例是带有计时器的解决方案的概念证明。带有BeginDate的细胞背景每秒会将其颜色从橙色更改为透明。EmployeesListViewModel是带有DataGrid的控件的DataContext。不要忘记为每个EmployeeDetailsViewModel调用StopTimer(),以防止内存泄漏
XAML
C#
公共类EmployeesListViewModel:INotifyPropertyChanged
{
私人可观察收集的员工;
公共雇员列表视图模型()
{
_员工=新的可观察集合();
_Add(newemployeedetailsviewmodel(){BeginDate=DateTime.Now});
_Add(newemployeedetailsviewmodel(){BeginDate=DateTime.Now.AddDays(1)});
}
公开收集雇员
{
获取{return\u employees;}
}
}
公共类EmployeeDetailsViewModel:INotifyPropertyChanged
{
Dispatchermer\u timer=null;
公共雇员详细信息模型()
{
_计时器=新调度程序();
_timer.Interval=TimeSpan.FromSeconds(1);
_timer.Tick+=(s,e)=>{OnPropertyChanged(“BeginDate”);};
_timer.Start();
}
公共无效停止计时器()
{
_timer.Stop();
}
私人日期时间;
公共日期时间开始
{
获取{return\u beginDate;}
设置
{
_beginDate=值;
不动产变更(“开始日期”);
}
}
公共事件属性更改事件处理程序属性更改;
受保护的虚拟void OnPropertyChanged(字符串propertyName)
{
if(this.PropertyChanged!=null)
{
var e=新的PropertyChangedEventArgs(propertyName);
本。财产变更(本,e);
}
}
}
公共类ColorBeginDateConverter:IValueConverter
{
公共对象转换(对象值,类型targetType,
对象参数,CultureInfo(区域性)
{
尝试
{
如果(DateTime.Now.Second%2==0)
返回刷。透明;
其他的
返回刷。橙色;
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Tick += (s, e) => OnPropertyChanged("BeginDate");
_timer.Start();
// Do no forget to stop timer when VM is no longer needed to prevent memory leak
_timer.Stop();
<UserControl.Resources>
<ResourceDictionary>
<local:ColorBeginDateConverter x:Key="beginDate" />
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<DataGrid Name="gridEmployees" ItemsSource="{Binding Employees}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="BeginDate" Binding="{Binding BeginDate}">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Background" Value="{Binding BeginDate, Converter={StaticResource beginDate} }" />
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
public class EmployeesListViewModel : INotifyPropertyChanged
{
private ObservableCollection<EmployeeDetailsViewModel> _employees;
public EmployeesListViewModel()
{
_employees = new ObservableCollection<EmployeeDetailsViewModel>();
_employees.Add(new EmployeeDetailsViewModel() { BeginDate = DateTime.Now });
_employees.Add(new EmployeeDetailsViewModel() { BeginDate = DateTime.Now.AddDays(1) });
}
public ObservableCollection<EmployeeDetailsViewModel> Employees
{
get { return _employees; }
}
}
public class EmployeeDetailsViewModel : INotifyPropertyChanged
{
DispatcherTimer _timer = null;
public EmployeeDetailsViewModel()
{
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Tick += (s, e) => { OnPropertyChanged("BeginDate"); };
_timer.Start();
}
public void StopTimer()
{
_timer.Stop();
}
private DateTime _beginDate;
public DateTime BeginDate
{
get { return _beginDate; }
set
{
_beginDate = value;
OnPropertyChanged("BeginDate");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
var e = new PropertyChangedEventArgs(propertyName);
this.PropertyChanged(this, e);
}
}
}
public class ColorBeginDateConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
try
{
if (DateTime.Now.Second % 2 == 0)
return Brushes.Transparent;
else
return Brushes.Orange;
}
catch (Exception)
{
return Brushes.Transparent;
}
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
return "not implemented";
}
}