【问题标题】:Style A Single XAML Item That Is Populated With Data Binding为使用数据绑定填充的单个 XAML 项设置样式
【发布时间】:2013-12-16 03:01:40
【问题描述】:

我有一个 C# ObservableCollection<>,它正在填充一个 XAML <ListBox>,其中每个项目都使用 <DataTemplate>。所述列表只是日期/内容对的列表,其中一对是今天(无论您查看它的哪一天)日期。我想做的是给“今天的”一对“嘶嘶声”(从技术上讲,只需设置.Foreground = (Brush)Resources["PhoneAccentBrush"];)。

现在,如果您注意到 /* using ObservableCollection<> 块,我已经完成了 Insert() 所期望的。我只是想做同样的事情,使用<DataTemplate>,因为这似乎是一种更合适的编码方式。

顺便说一句...我包含代码冗长级别的唯一原因是,总是有人会要求更多代码,而 cmets 可能会帮助某人(我知道我得到了很大的帮助,来自其他)。

XAML:

<ListBox x:Name="readingschedule" ItemsSource="{Binding}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock FontSize="20" TextWrapping="Wrap" FontWeight="SemiBold" Text="{Binding Date}"/>
                <TextBlock FontSize="27" TextWrapping="Wrap" Margin="0, 0, 0, 20" Text="{Binding Chapter}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
<!-- replacing with data template
<StackPanel x:Name="readingschedule"/>
-->

C#:

public MainPage()
{
    InitializeComponent();

    // get daily bible reading json results
    dailyBibleReading();

    // data binding for reading schedule
    readingschedule.DataContext = collection_readingschedule;

    // data binding for today's chapter
    todayschapter.DataContext = collection_todayschapter;
}

// create a collection (like an array) for the binding data to be added to
public ObservableCollection<ReadingSchedule> collection_readingschedule = new ObservableCollection<ReadingSchedule>();
// class to define the parts of the collection
public class ReadingSchedule
{
    public ReadingSchedule() { }
    public ReadingSchedule(string date, string chapter)
    {
        Date = date;
        Chapter = chapter;
    }
    public string Date { get; set; }
    public string Chapter { get; set; }
}

// create a collection (like an array) for the binding data to be added to
public ObservableCollection<TodaysChapter> collection_todayschapter = new ObservableCollection<TodaysChapter>();
// class to define the parts of the collection
public class TodaysChapter
{
    public TodaysChapter() { }
    public TodaysChapter(string reference, string text)
    {
        Reference = reference;
        Text = text;
    }
    public string Reference { get; set; }
    public string Text { get; set; }
}

// json connecting and processing example (http://nkishorchandra.blogspot.in/2012/10/parsing-json-in-windows-phone.html)
public void dailyBibleReading()
{
    // the the daily bible reading information for the whole week surrounding today
    DateTime today = DateTime.Today;
    // define default variables
    DateTime begindate = DateTime.Today.AddDays(-7);
    DateTime enddate = DateTime.Today.AddDays(7);
    DayOfWeek day = today.DayOfWeek;
    // redefine variables
    if (day == DayOfWeek.Sunday)
    {
        begindate = DateTime.Today.AddDays(-6);
        enddate = DateTime.Today.AddDays(5);
    }
    if (day == DayOfWeek.Monday)
    {
        begindate = DateTime.Today;
        enddate = DateTime.Today.AddDays(4);
    }
    if (day == DayOfWeek.Tuesday)
    {
        begindate = DateTime.Today.AddDays(-1);
        enddate = DateTime.Today.AddDays(3);
    }
    if (day == DayOfWeek.Wednesday)
    {
        begindate = DateTime.Today.AddDays(-2);
        enddate = DateTime.Today.AddDays(2);
    }
    if (day == DayOfWeek.Thursday)
    {
        begindate = DateTime.Today.AddDays(-3);
        enddate = DateTime.Today.AddDays(1);
    }
    if (day == DayOfWeek.Friday)
    {
        begindate = DateTime.Today.AddDays(-4);
        enddate = DateTime.Today;
    }
    if (day == DayOfWeek.Saturday)
    {
        begindate = DateTime.Today.AddDays(-5);
        enddate = DateTime.Today.AddDays(6);
    }
    string url = "http://www.flcbranson.org/api/dailybiblereading?begindate=" + begindate + "&enddate=" + enddate;

    WebClient dailyBibleReading = new WebClient();
    dailyBibleReading.DownloadStringCompleted += new DownloadStringCompletedEventHandler(dailyBibleReading_DownloadStringCompleted);
    dailyBibleReading.DownloadStringAsync(new Uri(url));
}
void dailyBibleReading_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    // do something with the feed here
    //string data = e.Result;
    //MessageBox.Show(data);
    // using Json.NET to deserialize the JSON content (http://json.codeplex.com/)
    // don't forget to include "using Newtonsoft.Json;" at the top
    // <RootObject> is the name of a class
    var rootObject = JsonConvert.DeserializeObject<RootObject>(e.Result);

    // used to specify insert position of textblocks (below)
    int schedule_position = 0;
    int fontsize = 27;
    foreach (var chapter in rootObject.dailychapter)
    {
        //MessageBox.Show(chapter.date);
        //MessageBox.Show(chapter.verses[0].text);

        // reading schedule
        // great examples of working with dates (http://www.dotnetperls.com/datetime)
        string chapter_date = chapter.date;
        // Friday, November 3, 2013
        string chapter_date_readable = DateTime.Parse(chapter_date).ToString("D");
        string chapter_book = chapter.book;
        int chapter_chapter = chapter.chapter;
        string chapter_reference = chapter_book + " " + chapter_chapter;
        //MessageBox.Show("The chapter for " + chapter_date_readable + " is " + chapter_reference + ".");

        // Add items to the collection.
        collection_readingschedule.Add(new ReadingSchedule(chapter_date_readable, chapter_reference));

        /* using ObservableCollections<>
        // create new textblocks for each verse (requires an x:Name element to already be present in xaml)
        TextBlock schedule_date = new TextBlock();
        // textblock properties (http://msdn.microsoft.com/en-us/library/system.windows.controls.textblock.fontsize(v=vs.110).aspx)
        schedule_date.Text = chapter_date_readable;
        // font weight names (http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.fontweights(v=vs.105).aspx)
        schedule_date.FontWeight = FontWeights.SemiBold;
        schedule_date.TextWrapping = TextWrapping.Wrap;
        schedule_date.FontSize = fontsize * 0.75;
        // readingschedule is the x:Name that is already present in xaml
        readingschedule.Children.Insert(schedule_position, schedule_date);
        // increment the position
        schedule_position++;

        // create new textblocks for each verse (requires an x:Name element to already be present in xaml)
        TextBlock schedule_reference = new TextBlock();
        // textblock properties (http://msdn.microsoft.com/en-us/library/system.windows.controls.textblock.fontsize(v=vs.110).aspx)
        schedule_reference.Text = chapter_reference;
        schedule_reference.TextWrapping = TextWrapping.Wrap;
        schedule_reference.FontSize = fontsize;
        schedule_reference.Margin = new Thickness(0, 0, 0, fontsize * 0.75);
        // readingschedule is the x:Name that is already present in xaml
        readingschedule.Children.Insert(schedule_position, schedule_reference);
        // increment the position
        schedule_position++;
        */

        // today's chapter
        // 2013-11-03
        string iso8601 = DateTime.Today.ToString("yyyy-MM-dd");
        if (chapter.date == iso8601) {
            /*
            // give today's chapter reference a little pizzaz
            schedule_date.Foreground = (Brush)Resources["PhoneAccentBrush"];
            schedule_reference.Foreground = (Brush)Resources["PhoneAccentBrush"];
            */

            // used to specify insert position of textblocks (below)
            int verse_position = 0;
            foreach (var verse in chapter.verses)
            {
                //MessageBox.Show(verse.text);
                int number = verse.number;
                string text = verse.text;

                // Add items to the collection.
                collection_todayschapter.Add(new TodaysChapter(chapter_reference + ":" + number, text));

                /* using ObservableCollection<>
                // create new textblocks for each verse (requires an x:Name element to already be present in xaml)
                TextBlock verse_reference = new TextBlock();
                // textblock properties (http://msdn.microsoft.com/en-us/library/system.windows.controls.textblock.fontsize(v=vs.110).aspx)
                verse_reference.Text = chapter_reference + ":" + number;
                // font weight names (http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.fontweights(v=vs.105).aspx)
                verse_reference.FontWeight = FontWeights.SemiBold;
                verse_reference.TextWrapping = TextWrapping.Wrap;
                verse_reference.FontSize = fontsize * 0.75;
                // todayschapter is the x:Name that is already present in xaml
                todayschapter.Children.Insert(verse_position, verse_reference);
                // increment the position
                verse_position++;

                // create new textblocks for each verse (requires an x:Name element to already be present in xaml)
                TextBlock verse_text = new TextBlock();
                // textblock properties (http://msdn.microsoft.com/en-us/library/system.windows.controls.textblock.fontsize(v=vs.110).aspx)
                verse_text.Text = text;
                verse_text.TextWrapping = TextWrapping.Wrap;
                verse_text.FontSize = fontsize;
                verse_text.LineHeight = fontsize * 1.25;
                verse_text.Margin = new Thickness(0, 0, 0, fontsize * 0.75);
                // todayschapter is the x:Name that is already present in xaml
                todayschapter.Children.Insert(verse_position, verse_text);
                // increment the position
                verse_position++;
                */
            }
        }
    }
}

// classess for the daily bible reading api json result
// classes generated by json2csharp (http://json2csharp.com)
// generated class names were a little odd so I made them more appropriate
public class Verses
{
    public int number { get; set; }
    public string text { get; set; }
}
public class DailyChapter
{
    public string date { get; set; }
    public string book { get; set; }
    public int chapter { get; set; }
    public List<Verses> verses { get; set; }
}
public class RootObject
{
    public List<DailyChapter> dailychapter { get; set; }
}

另外,如果您发现某些事情很愚蠢,请随时指出更好的做事方式。我对 C# 和 XAML 非常陌生。我确信有更好的方法来做我正在做的事情。我只是不认识他们。其中很多只是在修改示例代码和其他内容。

编辑...

Another thread 表示 Windows Phone 不支持 DataTemplate.Triggers。还有其他方法吗?

【问题讨论】:

标签: c# xaml data-binding windows-phone datatemplate


【解决方案1】:

您可以使用DataTrigger

<DataTemplate>
    <StackPanel x:Name="sp">
        <TextBlock FontSize="20" TextWrapping="Wrap" FontWeight="SemiBold" Text="{Binding Date}"/>
        <TextBlock FontSize="27" TextWrapping="Wrap" Margin="0, 0, 0, 20" Text="{Binding Chapter}"/>
    </StackPanel>

    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Date.Date}" Value="{x:Static sys:DateTime.Today}">
            <Setter TargetName="sp" Property="Background" Value="Red" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

【讨论】:

  • Microsoft DataTemplate.Triggers Property Page 提供此信息Namespace: System.Windows Assembly: PresentationFramework (in PresentationFramework.dll) XMLNS for XAML: http://schemas.microsoft.com/winfx/2006/xaml/presentation, http://schemas.microsoft.com/netfx/2007/xaml/presentation。这是需要添加到 xaml 顶部的东西吗?我在&lt;DataTemplate.Triggers&gt; 下得到一条波浪线,上面写着The member "Triggers" is not recognizable or is not accessible.
  • 你需要添加xmlns:sys="clr-namespace:System;assembly=mscorlib",但除此之外什么都没有。
  • 嗯...这不在我的 xaml 中,但添加它并不能修复波浪形。值得注意的是,这是一个 Windows Phone 7 应用程序。引用的属性页注明了 .NET,但没有注明任何 Windows Phone 版本。我一直在查看的页面顶部显示的是 Windows Phone 7.1 或 Windows Phone 8。也许这个特定的属性在那个舞台上不存在?
【解决方案2】:

为了使您的视图模型更通用,我建议在 ReadingSchedule 类中使用布尔属性 IsToday。因此,您的 ReadingSchedule 课程将如下所示:

public class ReadingSchedule
{
    public ReadingSchedule() { }
    public ReadingSchedule(string date, string chapter)
    {
        Date = date;
        Chapter = chapter;
    }

private bool _isToday;
public bool IsToday
{
    get { return _isToday; }
    private set { _isToday = value; }
}

private string _date;
public string Date 
{
    get { return _date; }
    set
    {
        if (Convert.ToDateTime(value).Day == DateTime.Now.Day)
            IsToday = true;
        _date = value;
    }
}

public string Chapter { get; set; }
}

然后对视图的更改就像使用 DataTrigger 检查 IsToday 值是否为 true 一样简单

<DataTemplate>
    <StackPanel x:Name="sp">
        <TextBlock FontSize="20" TextWrapping="Wrap" FontWeight="SemiBold" Text="{Binding Date}"/>
        <TextBlock FontSize="27" TextWrapping="Wrap" Margin="0, 0, 0, 20" Text="{Binding Chapter}"/>
    </StackPanel>

    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding IsToday}" Value="true">
            <Setter TargetName="sp" Property="Background" Value="Red" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

我认为这样做可能比在视图中比较日期更好,因为它不太关心逻辑。

【讨论】:

  • 哇,你刚刚输入了一堆我无法理解的东西。呵呵……不过,我会开始研究它。感谢 C# 示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-23
  • 2014-09-26
  • 2017-04-07
  • 2010-12-19
  • 1970-01-01
  • 1970-01-01
  • 2018-06-14
相关资源
最近更新 更多