在Windows应用商店应用中更改XML文本样式

时间:2015-04-20 13:59:14

标签: c# xml windows-store-apps

我正在创建一个应用程序,其中包含一个内容表。 我创建了一个XML文件来从中提取数据。 在我的XML中,我想改变一些文本的风格,但是我无法从XML代码中做到这一点。我尝试将标记放入<b><bold><strong>,但它们无法正常工作

请在下面找到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>

这是我的XML。如您所见,我有两种类型:ModuleUnit。我想在类型模块中使文本变为粗体,并在单元类型中缩进文本。

我还创建了一个类来调用标题。 我将向您展示以下代码:

这是我的班级

public class ContentTable
{
    string itemTitle;
    public string ItemTitle
    {
        get { return itemTitle; }
        set { itemTitle = value; }
    }
}

这是检索数据的代码。

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>

1 个答案:

答案 0 :(得分:3)

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

请注意,无论您最近做什么,您希望基于格式更改的条件都必须从原始数据流向渲染输出。有很多方法可以实现这一点,但是根据您的示例,在我看来,最简单的方法是向ContentTable类添加属性:

public class ContentTable
{
    public string ItemTitle { get; set; }
    public string ItemType { get; set; }
}

在您原来的ItemTitle媒体资源中,我添加了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属性(例如FontWeightMargin)之前,我们需要一些转换器来映射特定的stringtype的相应属性值的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个实例):

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

以上将两个不同的属性FontWeightMargin绑定到同一数据项属性ItemType。但由于它们使用不同的转换器,因此它们各自都表现得恰当当ItemType值为Module时,字体粗细设置为粗体;否则,它设置为正常重量。同样,当ItemType值为Unit时,左边距设置为非零值(在本例中,我选择20);否则,它的左边设置为0厚度。


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

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