【问题标题】:RichTextBox with variable number of bound runs绑定运行次数可变的 RichTextBox
【发布时间】:2013-04-11 20:47:59
【问题描述】:

我最近在做一个项目,我觉得一个不错的解决方案是在RichTextBox 中显示一个段落,该段落绑定到一个对象集合,该集合将包含一个字符串和一些关于该字符串的属性。我希望我能做这样的事情:

<RichTextBox Name="rtb" IsReadOnly="True" FontSize="14" FontFamily="Courier New">
    <FlowDocument>
        <Paragraph>
            <Run Foreground="Red" Text="{Binding foo}"/>
            <Run Foreground="Green" Text="{Binding bar}"/>
            <Run Foreground="Blue" Text="{Binding baz}"/>
        </Paragraph>
    </FlowDocument>
</RichTextBox>

这很好用,但是这是提前定义了所有绑定,但实际上我直到运行时才知道它们,每个字符串都将存储到一个集合中。我试图想出一种方法来定义和绑定多个 Run 块并将它们全部放在要显示的 RichTextBox 中。如果可能的话,我更喜欢主要的 xaml 解决方案,但如果我必须在后面的代码中这样做,那可能没问题,只要绑定保持不变并且在初始加载后一切都正确更新。

我尝试了类似的方法,但无法确定如何从后面的代码绑定到 RunText 属性:

foreach (var item in col)
{        
    Run run = new Run();
    Binding b = new Binding();
    b.Source = this;
    b.Path = new PropertyPath(item.StaticText);
    run.SetBinding(run.Text, b);    //Tells me Text is not a dependency property
                                    //But it could be bound if this were xaml?
}

我还尝试在RichTextBox 中放置一个ItemsControl,该Run 作为项目的数据模板,但它不允许我将数据模板设为Run 标签,并且我'我不确定这是否会奏效。

关于最佳方法的任何指导,或者我的解决方案有什么问题。

【问题讨论】:

    标签: c# wpf xaml richtextbox


    【解决方案1】:

    你可以用这个……

    <Paragraph>
        <ItemsControl ItemsSource="{Binding MyRuns}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock>
                        <Run Foreground="{Binding Color}" Text="{Binding Text}"/>
                    </TextBlock>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate >
                    <StackPanel Orientation="Vertical" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
        <!--<Run Foreground="Red" Text="{Binding foo}"/>
        <Run Foreground="Green" Text="{Binding bar}"/>
        <Run Foreground="Blue" Text="{Binding baz}"/>-->
    </Paragraph>
    

    并将MyRuns 定义为视图模型上的集合,例如

    public ObservableCollection<RunData> MyRuns { get; set; }  
    

    将属性放在您的RunData 等中。

    你当然可以删除ItemsControl.ItemsPanel,这只是为了好玩

    【讨论】:

      【解决方案2】:

      这似乎为我完成了工作,我创建了一个ItemsControl,它使用WrapPanel 作为ItemsPanel。然后我可以将每个项目绑定到我的字符串集合,它看起来就像一段漂亮的可变字符串。尽管有人提出更优雅的解决方案,但我会保持这个问题的开放性。

      <RichTextBox Name="rtb" IsReadOnly="True">
          <FlowDocument>
              <Paragraph>
                  <ItemsControl ItemsSource="{Binding col}">
                      <ItemsControl.ItemsPanel>
                          <ItemsPanelTemplate>
                              <WrapPanel/>
                          </ItemsPanelTemplate>
                      </ItemsControl.ItemsPanel>
                      <ItemsControl.ItemTemplate>
                          <DataTemplate>
                              <TextBlock>
                                  <TextBlock Text="{Binding StaticText,
                                      UpdateSourceTrigger=PropertyChanged}"/><TextBlock Text=" "/>
                              </TextBlock>
                          </DataTemplate>
                      </ItemsControl.ItemTemplate>
                  </ItemsControl>
              </Paragraph>
          </FlowDocument>
      </RichTextBox>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-02-04
        • 2010-09-25
        • 1970-01-01
        • 1970-01-01
        • 2011-01-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多