WinRT-XAML中绑定文本块的条件格式设置

3

一个月前我开始了我的应用程序开发,这是我第一次构建移动应用程序并第一次使用XAML,尽管我之前有一些C#的经验。

这是我使用的数据格式:

idAyat  namaKitab   abbKitab   numBab   numAyat  isi
  1     kejadian      kej        1         1     some long string to process blah blah
  2     kejadian      kej        1         2     some long string to process blah blah
  3     kejadian      kej        1         3     some long string to process query blah
  4     kejadian      kej        1         4     some long string to process blah query
  5     kejadian      kej        1         5     some query string to process blah blah

This is my XAML code :

<GridView x:Name="gvResult">
    <GridView.ItemsPanel>
        <ItemsPanelTemplate>
            <local:WrapPanel
                Orientation="Vertical"/>
        </ItemsPanelTemplate>
    </GridView.ItemsPanel>
    <GridView.ItemTemplate>
        <DataTemplate>
            <Grid Margin="5">
                <Grid.RowDefinitions>
                    <RowDefinition Height="auto"/>
                    <RowDefinition Height="auto"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="300" />
                </Grid.ColumnDefinitions>
                <TextBlock Width="300" TextWrapping="Wrap">
                    <Underline>
                        <Run FontWeight="Medium" Text="{Binding abbKitab}"/><Run Text=" "/><Run FontWeight="Medium" Text="{Binding numBab}"/>
                        <Run FontWeight="Medium" Text=":"/> <Run FontWeight="Medium" Text="{Binding numAyat}"/>
                    </Underline>
                    <LineBreak/>
                    <Run Text="{Binding isi}"/>
                </TextBlock>
            </Grid>
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>

我正在尝试创建一个搜索结果页面,该页面可以将用户输入的“查询”加粗或更改前景色。 我阅读了许多文章,并发现一个线程(这里的链接已经失效)说我们无法从后台代码更改样式设置器。
假设文章是正确的,我该如何在我的页面中更改文本块的前景色呢? 更具体地说,我只想更改与搜索查询匹配的单词的颜色。
我认为可能更像这样:
<Style x:Key="PriorityStyle" TargetType="TextBlock" >
    <Setter Property="Foreground" Value="#6c6d6f" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding Priority}" Value="Critical">
            <Setter Property="Foreground" Value="Red"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

(编辑) 显然上面的代码不支持WINRT-XAML,它是WPF-XAML

但是如何使用这个代码来定位特定的单词?有什么建议吗?

谢谢。


我在你的数据中没有看到“Priority”(优先级)这个属性,但是假设它存在,我会将TextBlock的Foreground属性绑定到Priority,并使用值转换器将其转换为Brush。 - Denis
你说得对,那个代码块是从这里的链接(http://stackoverflow.com/a/15624365/2297716)来的。 - Alvin Setiawan
如果您看到上面的UPDATE部分,它是针对WPF的,我不知道如何在WINRT-XAML上实现这一点。我正在尝试弄清楚如何更改与用户SearchQuery匹配的“isi”列中的某些文本的Foreground属性,在本例中为上述数据中的“query”单词。我已经尝试在搜索过程之后处理该列,向所选单词添加<bold></bold>标记,但显然这也行不通,<bold>无法转换为样式值,它变成了字符串值。 - Alvin Setiawan
2个回答

2
感谢大家在这里提供的所有答案。但最终,我想到了这个:
这是来自SearchResultPage.xaml的我的XAML代码:
   <GridView x:Name="gvResult">
        <GridView.ItemsPanel>
            <ItemsPanelTemplate>
                <local:WrapPanel2
                    Orientation="Vertical"/>
            </ItemsPanelTemplate>
        </GridView.ItemsPanel>
        <GridView.ItemTemplate>
            <DataTemplate>
                <local:SearchResultUC/>
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>

这是我的SearchResultUC:

<UserControl
    x:Class="BibleApps.SearchResultUC"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:BibleApps"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400">

    <Grid Margin="5">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="300" />
        </Grid.ColumnDefinitions>
        <TextBlock Width="300" Grid.Row="0" >
                <Underline>
                    <Run FontWeight="Medium" Text="{Binding abbKitab}"/><Run Text=" "/><Run FontWeight="Medium" Text="{Binding numBab}"/>
                    <Run  FontWeight="Medium" Text=":"/> <Run FontWeight="Medium" Text="{Binding numAyat}"/>
                </Underline>
        </TextBlock>
        <TextBlock TextWrapping="Wrap" Grid.Row="1" local:FormattedTextBehavior.FormattedText="{Binding isi}"/>
    </Grid>
</UserControl>

这是FormattedTextBehavior.cs的答案:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Documents;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using BibleApps.Common;
using BibleApps.DataModel; 

namespace BibleApps
{
    public class FormattedTextBehavior : DependencyObject
    {
        public static string GetFormattedText(DependencyObject obj)
        {
            return (string)obj.GetValue(FormattedTextProperty);
        }

        public static void SetFormattedText(DependencyObject obj, string value)
        {
            obj.SetValue(FormattedTextProperty, value);
        }

        public static readonly DependencyProperty FormattedTextProperty =
            DependencyProperty.RegisterAttached("FormattedText",
                                                typeof(string),
                                                typeof(FormattedTextBehavior),
                                                new PropertyMetadata("", FormattedTextChanged));

        private static void FormattedTextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            TextBlock textBlock = sender as TextBlock;
            string value = e.NewValue as string;
            string[] tokens = value.Split(' ');
            string[] querytokens = SuspensionManager.SessionState["query"].ToString().Split(' ');
            foreach (string token in tokens)
            {
                Run kata = new Run();
                bool ketemu = false;
                foreach (string querytoken in querytokens)
                {
                    if (token.ToLower().Contains(querytoken.ToLower())) {
                        ketemu = true;
                        break;
                    }
                }
                if (ketemu){
                    kata.Foreground = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 0, 255, 80));
                    kata.FontWeight = Windows.UI.Text.FontWeights.Bold;
                    kata.Text = token + " ";
                    textBlock.Inlines.Add(kata);
                }
                else {
                    kata.Text = token + " ";
                    textBlock.Inlines.Add(kata);
                }
            }
        }
    }
}

我感谢您的时间和思考,这真的非常有帮助。谢谢 :)

2

由于WinRT中未实现WPF触发器,因此您可以在GridView上定义一个DataTemplateSelector。

在此模板选择器中,定义两个模板,一个用于“常规”条目,另一个用于“搜索”条目。

在模板选择器的SelectTemplate方法中,只需测试数据对象的属性,以检查是否必须应用一个模板或另一个模板。


2
一个简单而正确的解决方案。您可以在http://diptimayapatra.wordpress.com/2012/07/24/data-template-selector-in-windows-8-metro-xaml-app/了解有关DataTemplateSelectors的信息。实际上非常简单。 - Stephen Hosking

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接