【问题标题】:How do I bind rich text (FlowDocument?) from my view model to a RichTextBlock?如何将富文本(FlowDocument?)从我的视图模型绑定到 RichTextBlock?
【发布时间】:2012-11-09 03:33:02
【问题描述】:

我能在网上找到的将文本绑定到 WinRT RichTextBlock 的唯一示例如下所示:

<RichTextBlock>
    <Paragraph>
        <Run Text="{Binding Content}"/>
    </Paragraph>
</RichTextBlock>

我能找到的实际显示富文本的唯一示例如下所示:

<RichTextBlock>
    <Paragraph>
        <Run>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ligula nisi, vehicula nec eleifend vel, rutrum non dolor. Vestibulum ante ipsum primis in faucibus orci</Run>
        <Run FontSize="30">luctus</Run>
        <Run>et ultrices posuere cubilia Curae; Curabitur elementum scelerisque accumsan. In hac habitasse platea dictumst. Maecenas eu nibh vitae nibh laoreet placerat. Duis dolor ante, semper luctus ullamcorper eget, placerat et ligula. Donec placerat tincidunt vehicula. Fusce condimentum lacus quis libero blandit semper sed vel quam. Proin eget nisl lacinia nibh convallis scelerisque at sed massa. Duis commodo tincidunt consequat. Duis malesuada, nisl a pharetra placerat, odio dui suscipit quam, vitae rhoncus sem risus quis odio. Aliquam justo nunc, adipiscing id elementum sit amet, feugiat vel enim. Aliquam pharetra arcu nec elit luctus euismod. Suspendisse potenti.</Run>
    </Paragraph>
</RichTextBlock>

如何将RichTextBlock 的文本数据绑定到我的视图模型中可能包含多个段落并运行的属性?该视图模型属性需要是什么类型?

我看到了一些关于使用FlowDocument 的参考,但我不知道这是否适用于RichTextBlock。但是,即使是这些示例也没有显示任何与文档的数据绑定。

【问题讨论】:

  • 我正在为这个应用切换到 HTML/CSS/JavaScript。 HTML/CSS 中的文本显示似乎更容易。尤其是当您想要多列时。

标签: xaml data-binding windows-8 winrt-xaml


【解决方案1】:

RichTextBlock 似乎不提供文档绑定。相反,您可以使用自定义 RichTextBlock 控件来实现它。你可以试试Bindable RichTextBlock

【讨论】:

  • 他在该博客文章中扩展的 RichTextBox 控件对于 winRT XAML 似乎不存在。
  • 恕我直言,它应该通过继承 RichTextBlock 而不是 RichTextBox 来工作。让我们知道您的冒险经历。
  • Windows 8 控件RichTextBlock 是密封的,因此不能从它继承。
【解决方案2】:

我遇到了同样的问题,我的解决方案是手动完成。

  1. 订阅 view.xaml.cs 中的 notifyPropertyChanged
  2. 发生更新时,检查是否是您的资源已更新
  3. 如果是这样,请更新您的RichTextBlock

这里是代码。

private void Page_OnLoaded(object sender, RoutedEventArgs e)
        {    
            SetReferences();
            (DataContext as INotifyPropertyChanged).PropertyChanged += OnPropertyChanged;
        }

        private void Page_OnUnloaded(object sender, RoutedEventArgs e)
        {
            (DataContext as INotifyPropertyChanged).PropertyChanged -= OnPropertyChanged;
        }

        private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            var propertyName = GetPropertyName<MyViewModel, object>(x => x.References); // I use this to avoid bugs at runtime
            if (e.PropertyName == propertyName)
                SetReferences();
        }

        private void SetReferences()
        {
            var references = (DataContext as MyViewModel).References;
            ReferencesRichTextBlock.Blocks.Clear();
            foreach (var reference in references)
            {
                var paragraph = new Paragraph();
                paragraph.Inlines.Add(new Run { Text = reference.Title, FontWeight = FontWeights.Bold});
                paragraph.Inlines.Add(new Run { Text = " : "});
                paragraph.Inlines.Add(new Run { Text = reference.Content});
                paragraph.Inlines.Add(new LineBreak());

                ReferencesRichTextBlock.Blocks.Add(paragraph);
            }
        }

        public static string GetPropertyName<T, P>(Expression<Func<T, P>> action) where T : class
        {
            var expression = (MemberExpression)action.Body;
            var name = expression.Member.Name;

            return name;
        }

当然,这是 xaml

<Page ...
      Loaded="Page_OnLoaded"
      Unloaded="Page_OnUnloaded">
...
<RichTextBlock x:Name="ReferencesRichTextBlock">

                            </RichTextBlock>
</Page>

【讨论】:

  • 这看起来很有希望。当我发布这个问题时,我从未完成我正在开发的应用程序,并且没有打算回到它,但也许有一个可行的答案我会再试一次。
【解决方案3】:

我已在我的一个项目中将数据绑定到 RichTextBlock。请参阅下面的 XAML。我正在绑定一些字符串值和一个图像。您可以在此处查看页面如何呈现的快照:

    <common:RichTextColumns x:Name="richTextColumns" Margin="117,0,117,47" VerticalAlignment="Top">
<RichTextBlock x:Name="richTextBlock" Width="560" Style="{StaticResource ItemRichTextStyle}" TextWrapping="Wrap">
    <Paragraph>
    <Run FontSize="20" FontWeight="Light" Text="{Binding Title}"/>
    <LineBreak/>
    </Paragraph>
    <Paragraph LineStackingStrategy="MaxHeight">
    <InlineUIContainer>
        <ItemsControl ItemsSource="{Binding Authors}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
            <StackPanel Orientation="Vertical"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
            <StackPanel>
                <HyperlinkButton Content="{Binding}"
                    VerticalAlignment="Center" FontSize="14"
                    Tapped="AuthorSearchLinkTapped"
                    IsTapEnabled="True"
                    Padding="0, 0, 0, 0"/>
            </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        </ItemsControl>
    </InlineUIContainer>
    </Paragraph>
    <Paragraph LineStackingStrategy="MaxHeight">
    <InlineUIContainer>
        <Image x:Name="image" MaxHeight="200" Margin="0,20,0,10" Stretch="Uniform" Source="{Binding ImageUrl}"/>
    </InlineUIContainer>
    </Paragraph>
    <Paragraph LineStackingStrategy="MaxHeight">
    <InlineUIContainer>
        <Grid Width="560" Height="125" MaxHeight="125">
        <TextBlock Text="Loading ad..." 
               VerticalAlignment="Center" 
               HorizontalAlignment="Center"
               Style="{StaticResource BasicTextStyle}"/>
        <UI:AdControl ApplicationId="ec6615c8-dc88-4413-af37-1fc3b5603e85" 
                  AdUnitId="104236"
                  Width="250" Height="125"
                  HorizontalAlignment="Center"/>
        </Grid>
    </InlineUIContainer>
    </Paragraph>
    <Paragraph>
    <Run FontWeight="SemiLight" Text="{Binding Description}"/>
    </Paragraph>
</RichTextBlock>

<!-- Additional columns are created from this template -->
<common:RichTextColumns.ColumnTemplate>
    <DataTemplate>
    <RichTextBlockOverflow Width="560" Margin="80,0,0,0">
        <RichTextBlockOverflow.RenderTransform>
        <TranslateTransform X="-1" Y="4"/>
        </RichTextBlockOverflow.RenderTransform>
    </RichTextBlockOverflow>
    </DataTemplate>
</common:RichTextColumns.ColumnTemplate>
</common:RichTextColumns>

【讨论】:

  • 这本质上是我问题中第一个选项的扩展示例。如果您在设计时就知道格式,那就很容易了。但是我看不到这如何在绑定文本中提供任意粗体字。我需要通过数据绑定提供丰富的格式,而不是在页面 XAML 中预设。
【解决方案4】:

我也遇到过类似的情况。我想根据一些正在进行的操作使用状态消息更新 ReadOnly RichTextBox 的内容。这是我最终做的:

<UserControl 
  x:Class="RawhideCsControl.StorageViewUserControl2" 
  <!-- >

      <RichTextBox  x:Name="StatusText" HorizontalAlignment="Left"  Height="350.72" VerticalAlignment="Top" Width="636">
          <FlowDocument>
               <Paragraph>
                    <Run Text="{Binding Status}"></Run>
               </Paragraph>
          </FlowDocument>
      </RichTextBox>

  <!-- >
</UserControl>

代码:

    public partial class StorageViewUserControl2 : System.Windows.Controls.UserControl
    {
        // . . .

        StatusChanger statusChanger = new StatusChanger();
        private void AddStatusLine(string format, params object[] args)
        {
            if (args.Length > 0)
                format = string.Format(format, args);

            //m_StorageViewTreeModel.MirrorStatusDisplay += string.Format("{0}\r\n", format); 
            statusChanger.Status += string.Format("{0}\r\n", format);

        }//end this.AddStatusLine(str)

        // . . .
     } // end partial class


    public class StatusChanger : INotifyPropertyChanged
    {
        private string status = string.Empty;
        public string Status
        {
            get { return status; }
            set
            {
                status = value;
                OnPropertyChanged("Status");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged( string PropertyName )
        {
            if( PropertyChanged != null )
                PropertyChanged( this, new PropertyChangedEventArgs(PropertyName));
        }
    } // end class StatusChanger

【讨论】:

  • 我看不出这如何解决我的问题。这是否允许您在状态消息中包含一些粗体文本和一些普通文本?您的答案中没有显示任何丰富的格式。这看起来与我在问题中提出的显示数据绑定到字符串的内容相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多