C# 如何在WPF数据绑定中通知DateTime更改事件?

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

我有一个WPF应用程序,它使用这样的绑定

<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";
    }
}