根据DateTime更改ListBox项

时间:2015-04-07 15:32:03

标签: c# datetime windows-phone-7 listbox

我有一个ListBox,其中绑定了一些项目。这些项目是从如下文件中读取的:

        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的样子:

        <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项等)并且它不能解决我的问题。我希望能够在每次将文件加载到应用程序时检查截止日期是否超过当前日期并相应地进行更改。

我非常感谢你的帮助。

2 个答案:

答案 0 :(得分:0)

为了实现这一点,您首先要将属性Forecolor添加到Activity类中。此属性将是一个getter属性,它根据您的条件返回颜色(在这种情况下,如果当前日期大于截止日期,则返回Red else Green)。请注意,我已将截止日期数据类型更改为日期以允许比较日期。

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

现在将控件Foreground属性绑定到此属性Forecolor

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

由于Foreground属性需要一个Brush,它只能用于颜色绑定,你需要使用一个将Color转换为Brush的转换器。

在项目中定义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();
    }
}

最后在窗口资源中定义转换器。

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

注意:我已经从WPF项目中输入了代码。如果您的项目在WP7中,可能会出现一些语法问题(虽然我认为它应该可行)。但原则是一样的。

答案 1 :(得分:0)

你可以使用转换器来做这件事。

<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 - 您应该使用ObservableCollection而不是List来保存您的活动对象。另外,请确保您的activity对象支持INotifyPropertyChanged,并且所有属性方法都调用PropertyChanged。