C# 更改Windows应用商店应用程序中XML的文本样式

C# 更改Windows应用商店应用程序中XML的文本样式,c#,xml,windows-store-apps,C#,Xml,Windows Store Apps,我正在创建一个应用程序,其中包含一个目录。 我创建了一个XML文件来从中提取数据。 在我的XML中,我想改变一些文本的样式,但是从XML代码中我做不到。我试着放置标签,,,但它们不起作用 请在下面找到XML代码: <book> <item type="Module"> <title>My family and I</title> </item> <item type="Unit">

我正在创建一个应用程序,其中包含一个目录。 我创建了一个XML文件来从中提取数据。 在我的XML中,我想改变一些文本的样式,但是从XML代码中我做不到。我试着放置标签
,但它们不起作用

请在下面找到XML代码:

<book>
    <item type="Module">
      <title>My family and I</title>
    </item>
    <item type="Unit">
      <title>World Friends</title>
    </item>
    <item type="Unit">
      <title>Sport and activities</title>
    </item>
    <item type="Module">
      <title>
        <b>School days</b></title>
    </item>
    <item type="Unit">
      <title>My routine</title>
    </item>
    <item type="Unit">
      <title>School life</title>
    </item>
</book>
这是检索数据的代码

string XMLPath = Path.Combine(
   Package.Current.InstalledLocation.Path, "Assets/tableOfContent.xml");
XDocument loadedData = XDocument.Load(XMLPath);

//retrieving data from xml using LINQ     
var data = from query in loadedData.Descendants("item")
    select new ContentTable
    {
        ItemTitle = (string)query.Element("title")
    };

//assigning source to GridView Control     
AllItemsView.ItemsSource = data;
这是我的XAML

<ListBox x:Name="AllItemsView" Width="200" Margin="45,20,5,-604" Height="665" VerticalAlignment="Top" Foreground="Black" Background="White" Grid.RowSpan="2" SelectionChanged="AllItemsView_SelectionChanged">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Margin="10" >
                <TextBlock Text="{Binding ItemTitle}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

在编写WPF程序时,解决此问题的一个简单方法是为
TextBlock
声明
样式
,其中使用
DataTrigger
实例根据数据对
TextBlock
属性应用特定格式。不幸的是,这个特性(像许多其他非常有用的特性一样)不在WinRT中。据我所知,常见的替代方法是实现
IValueConverter
,将一些输入值映射到适合格式化的属性值。它不像触发器那样广泛地有用,但对于简单的场景,它的工作原理大致相同

请注意,无论最后执行什么操作,格式更改所基于的条件都必须从原始数据流向渲染输出。有多种方法可以实现这一点,但举个例子,在我看来,最简单的方法就是向
ContentTable
类添加属性:

public class ContentTable
{
    public string ItemTitle { get; set; }
    public string ItemType { get; set; }
}
在原始的
itemttitle
属性中,我添加了
ItemType
,它将从XML中获取
type
属性值

当然,添加此属性后,需要将其与
ItemTitle
一起填充:

var data = from query in loadedData.Descendants("item")
           select new ContentTable
           {
               ItemTitle = query.Element("title").Value,
               ItemType = query.Attribute("type").Value
           };
在将此新属性绑定到相关的
TextBlock
属性(例如
fontwweight
Margin
)之前,我们需要转换器将
type
属性中的特定
字符串
值映射到
TextBlock
的相应属性值:

class ItemTypeToBoldConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        string text = value as string;

        if (text != null)
        {
            return text == "Module" ?
                Windows.UI.Text.FontWeights.Bold :
                Windows.UI.Text.FontWeights.Normal;
        }

        return Windows.UI.Xaml.DependencyProperty.UnsetValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

class ItemTypeToMarginConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        string text = value as string;

        if (text != null)
        {
            return text == "Unit" ?
                new Windows.UI.Xaml.Thickness(20, 0, 0, 0) :
                new Windows.UI.Xaml.Thickness();
        }

        return Windows.UI.Xaml.DependencyProperty.UnsetValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}
在奠定了所有必要的基础之后,剩下的工作就很容易了。:)

您的转换器可以声明为资源(例如,可以将其重新用于多个元素,甚至不同的
DataTemplate
实例):


最后,您可以在模板本身中引用转换器:

<DataTemplate>
  <StackPanel Margin="10" >
    <TextBlock Text="{Binding ItemTitle}"
                FontWeight="{Binding ItemType, Converter={StaticResource itemTypeToBoldConverter1}}"
                Margin="{Binding ItemType, Converter={StaticResource itemTypeToMarginConverter1}}"/>
  </StackPanel>
</DataTemplate>

上面将两个不同的属性,
fontweaght
Margin
绑定到同一数据项属性,
ItemType
。但是,由于它们使用不同的转换器,因此每个转换器的行为都是适当的。当
ItemType
值为
Module
时,字体权重设置为粗体;否则,它将设置为正常重量。类似地,当
ItemType
值为
Unit
时,左边距设置为非零值(在本例中,我选择了
20
);否则,将其左设置为0厚度


请注意,上面将XML数据直接转换为XAML UI元素属性值。在您的问题中,您提到了HTML标记,如
。以上是最简单的方法,最符合您提供的确切代码示例和格式标准。但是你不能用它来应用HTML格式。您必须使用XAML中可用的格式和布局。现在,这实际上是一个非常丰富的格式化环境,但是如果您想要基于HTML的方法,您可以这样做


这里也有很多选项,但最好的方法是编写一个XSL样式表,将XML转换为适当的HTML文档,使用
XsltTransform
类进行转换(假设WinRT上有此功能…我没有检查)。然后您可以使用
WebView
控件(或在WPF中,
WebBrowser
)来显示HTML。

非常感谢,我也遇到了同样的问题,效果非常好!你知道这个问题吗@LayaleMatta:嗨……我看了你的问题,但不幸的是,我在Windows运行时API方面不够专业,无法理解你的问题,而不包括更多细节。我在那里添加了一条评论,解释我需要什么样的补充细节才能有机会帮助回答这个问题。也许其他人会更幸运地理解这个问题,但如果不是,并且如果你添加了要求的细节,我很高兴再看一眼。@PeterDuniho你知道我怎样才能改变背景色,以防我想让模块有一种特定的颜色,而让单元有另一种特定的颜色吗?@PascaleAboabdo:当然……用同样的技术就行了。编写一个新的IValueConverter,将
类型
值映射到某种颜色,并在绑定到
背景
属性时使用它。请注意,在这种情况下,one转换器将检查您关心的所有可能值,并为给定的
类型
值返回适当的颜色。请注意,
Background
属性实际上是一个
Brush
,因此您必须返回使用所需颜色创建的
SolidColorBrush
<Page.Resources>
  <local:ItemTypeToBoldConverter x:Key="itemTypeToBoldConverter1"/>
  <local:ItemTypeToMarginConverter x:Key="itemTypeToMarginConverter1"/>
</Page.Resources>
<DataTemplate>
  <StackPanel Margin="10" >
    <TextBlock Text="{Binding ItemTitle}"
                FontWeight="{Binding ItemType, Converter={StaticResource itemTypeToBoldConverter1}}"
                Margin="{Binding ItemType, Converter={StaticResource itemTypeToMarginConverter1}}"/>
  </StackPanel>
</DataTemplate>