简体   繁体   English

根据DateTime更改ListBox项

[英]Changing ListBox item depending on DateTime

I have a ListBox with some items bound to it. 我有一个列表框,其中绑定了一些项目。 Those items are read from files like so: 这些项目是从文件中读取的,如下所示:

        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;

        }

As you can see I'm reading dates and a title from the file name. 如您所见,我正在从文件名中读取日期和标题。 Afterwards I bind them to the ListBox. 之后,我将它们绑定到ListBox。 What I want to do is change ListBox item (2 textbox and a hyperlink) color each time the dateDeadline is past the current date. 我想做的是每次dateDeadline超过当前日期时都更改ListBox项(2个文本框和一个超链接)的颜色。

Here is how my ListBox looks like: 这是我的ListBox的样子:

        <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>

Every guide I found was dealing with particular ListBox item (like changing 3rd item, 4th item etc.) and it does not solve my problem. 我发现的每个指南都在处理特定的ListBox项(例如更改第3项,第4项等),但这不能解决我的问题。 I want to be able to check if the Deadline is past the current date each time files are loaded to the app and change it accordingly. 我希望每次文件加载到应用程序时都可以检查截止日期是否已超过当前日期,并进行相应的更改。

I'll greatly appreciate your help. 非常感谢您的帮助。

In order to achieve this, you would first want to add a property Forecolor to your Activity class. 为了实现此目的,您首先要向Activity类添加属性Forecolor。 This property will be a getter property that returns a color based on your condition (In this case, if the current date is greater than the deadline, return Red else Green). 此属性将是一个getter属性,该属性将根据您的条件返回颜色(在这种情况下,如果当前日期大于截止日期,则返回红色,否则返回绿色)。 Note that I have changed your Deadline data type to Date to allow comparison of dates. 请注意,我已将您的“截止日期”数据类型更改为“日期”以允许比较日期。

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

Now bind you controls Foreground property to this property Forecolor 现在将控件的“前景”属性绑定到该属性“前景色”

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

Since the Foreground property expects a Brush, it will not work with just a color binding, you will need to use a converter that converts a Color to a Brush. 由于“前景”属性期望使用“画笔”,因此它不能仅用于颜色绑定,因此您需要使用将“颜色”转换为“画笔”的转换器。

Define a Converter class in your project. 在您的项目中定义一个Converter类。

    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();
    }
}

Finally define the converter in your window resources. 最后,在窗口资源中定义转换器。

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

Note: I have put in code from a WPF project. 注意:我已经从WPF项目中输入了代码。 There may be a few syntax issues if your project is in WP7 (Though I think, it should work). 如果您的项目在WP7中,则可能存在一些语法问题(尽管我认为这应该可行)。 However the principle is the same. 但是原理是相同的。

You can use a converter for just such a thing. 您可以将转换器用于此类事情。

<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();
    }
}

BTW - you should use an ObservableCollection instead of a List to hold your activity objects. 顺便说一句-您应该使用ObservableCollection而不是List来保存您的活动对象。 Also, make sure your activity object supports INotifyPropertyChanged and that all your property methods call PropertyChanged. 另外,请确保您的活动对象支持INotifyPropertyChanged,并且所有属性方法都调用PropertyChanged。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM