根据日期时间更改列表框项目

Changing ListBox item depending on DateTime

我有一个列表框,上面绑定了一些项目。这些项目是从这样的文件中读取的:

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            bindList();
        }

        private void bindList()
        {
            var appStorage = IsolatedStorageFile.GetUserStoreForApplication();

            string[] fileList = appStorage.GetFileNames();

            List<Activity> activities = new List<Activity>();


            foreach (string file in fileList)
            {

                string fileName = file;

                string cYear = file.Substring(0, 4);
                string cMonth = file.Substring(5, 2);
                string cDay = file.Substring(8, 2);
                string cHour = file.Substring(11, 2);
                string cMinute = file.Substring(14, 2);
                string cSeconds = file.Substring(17, 2);

                DateTime dateCreated = new DateTime(int.Parse(cYear), int.Parse(cMonth), int.Parse(cDay), int.Parse(cHour), int.Parse(cMinute), int.Parse(cSeconds));

                string dYear = file.Substring(20, 4);
                string dMonth = file.Substring(25, 2);
                string dDay = file.Substring(28, 2);

                DateTime dateDeadline = new DateTime(int.Parse(dYear), int.Parse(dMonth), int.Parse(dDay));

                string aTitle = file.Substring(31);
                aTitle = aTitle.Substring(0, aTitle.Length - 4);
                activities.Add(new Activity() { Title = aTitle, DateCreated = dateCreated.ToLongDateString(), Deadline = dateDeadline.ToLongDateString(), FileName = fileName });

            }

            activityListBox.ItemsSource = activities;

        }

如您所见,我正在从文件名中读取日期和标题。之后我将它们绑定到 ListBox。我想要做的是每次 dateDeadline 超过当前日期时更改 ListBox 项目(2 个文本框和一个超链接)颜色。

这是我的列表框的样子:

        <ListBox HorizontalAlignment="Stretch"
                 Name="activityListBox"
                 VerticalAlignment="Stretch">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <HyperlinkButton Name="activityTitle"
                                         FontSize="40"
                                         Content="{Binding Title}"
                                         HorizontalContentAlignment="Left"
                                         Tag="{Binding FileName}"
                                         Click="activityTitle_Click"
                                          />

                        <TextBlock Name="activityDateCreated"
                                   Text="{Binding DateCreated, StringFormat='Stworzono: {0}'}"
                                   Margin="10" />

                        <TextBlock Name="activityDeadline"
                                   Text="{Binding Deadline, StringFormat='Deadline: {0}'}"
                                   Margin="10" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

我找到的每个指南都在处理特定的 ListBox 项目(比如更改第 3 项、第 4 项等),但它没有解决我的问题。我希望能够在每次将文件加载到应用程序时检查截止日期是否超过当前日期并相应地进行更改。

非常感谢你的帮助。

为了实现这一点,您首先要为 Activity class 添加 属性 前景色。这个 属性 将是一个 getter 属性 return 根据您的条件选择颜色(在这种情况下,如果当前日期晚于截止日期,return 红色否则绿色)。请注意,我已将您的 Deadline 数据类型更改为 Date 以允许比较日期。

public DateTime Deadline { get; set; }
public Color Forecolor
{
    get
    {
        if (DateTime.Now > Deadline)
            return Colors.Red;
        else
            return Colors.Green;
    }
}

现在将你的控件前景属性绑定到这个属性前景色

Foreground="{Binding Forecolor, Converter={StaticResource ColorToSolidColorBrush_ValueConverter}}"

由于前景 属性 需要一个画笔,它不能仅使用颜色绑定,您需要使用一个转换器将颜色转换为画笔。

在您的项目中定义一个转换器 class。

    public class ColorToSolidColorBrushValueConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (null == value)
        {
            return null;
        }
        // For a more sophisticated converter, check also the targetType and react accordingly..
        if (value is Color)
        {
            Color color = (Color)value;
            return new SolidColorBrush(color);
        }
        // You can support here more source types if you wish
        // For the example I throw an exception

        Type type = value.GetType();
        throw new InvalidOperationException("Unsupported type [" + type.Name + "]");
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // If necessary, here you can convert back. Check if which brush it is (if its one),
        // get its Color-value and return it.

        throw new NotImplementedException();
    }
}

最后在您的 window 资源中定义转换器。

<Window.Resources>
    <local:ColorToSolidColorBrushValueConverter  x:Key="ColorToSolidColorBrush_ValueConverter"/>
</Window.Resources>

注意:我已经输入了 WPF 项目的代码。如果您的项目在 WP7 中,则可能存在一些语法问题(尽管我认为它应该可以工作)。不过原理是一样的。

你可以使用转换器来完成这样的事情。

<UserControl.Resources>
    <ResourceDictionary>
        <local:DateToColorConverter x:Key="DateToColorConverter"/>
    </ResourceDictionary>
</UserControl.Resources>

...

<TextBlock Name="activityDateCreated"
    Text="{Binding DateCreated, StringFormat='Stworzono: {0}'}"                                  
    Margin="10"
    Foreground="{Binding Deadline, Converter={StaticResource DateToColorConverter}" />


...


Your Converter (put this in your code behind)...

public class DateToColorConverter : IValueConverter
{
    static SolidColorBrush _normalColor = new SolidColorBrush(Colors.Black);
    static SolidColorBrush _pastDeadlineColor = new SolidColorBrush(Colors.Red);

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is DateTime)
        {
            var deadline = value as DateTime;
            return deadline < DateTime.Now ? _pastDeadlineColor : _normalColor;
        }

        return _normalColor;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

顺便说一句 - 您应该使用 ObservableCollection 而不是 List 来保存您的 activity 对象。此外,请确保您的 activity 对象支持 INotifyPropertyChanged 并且您的所有 属性 方法都调用 PropertyChanged。