如何折叠段落?

发布于 2024-09-24 15:58:52 字数 42 浏览 4 评论 0原文

如何使 FlowDocument 中的段落可折叠,同时保持其文本可选?

How can I make a Paragraph collapsible in a FlowDocument while keeping its text selectable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

街角卖回忆 2024-10-01 15:58:52

这一定是有史以来最丑陋的扩展之一(就代码和视觉效果而言),但它“使段落可折叠”并且文本仍然可选。

public static class ParagraphExtensions
{
    private static Dictionary<Paragraph, InlineUIContainer> _collapseButtonDictionary;
    private static Dictionary<Paragraph, List<Inline>> _paragraphInlineStorage;

    public static readonly DependencyProperty IsCollapsibleProperty =
        DependencyProperty.RegisterAttached("IsCollapsible", typeof(bool), typeof(Paragraph), new UIPropertyMetadata(false, IsCollapsibleChanged));
    public static bool GetIsCollapsible(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsCollapsibleProperty);
    }
    public static void SetIsCollapsible(DependencyObject obj, bool value)
    {
        obj.SetValue(IsCollapsibleProperty, value);
    }

    private static void IsCollapsibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        if (_collapseButtonDictionary == null) _collapseButtonDictionary = new Dictionary<Paragraph, InlineUIContainer>();
        if (_paragraphInlineStorage == null) _paragraphInlineStorage = new Dictionary<Paragraph, List<Inline>>();

        Paragraph p = sender as Paragraph;
        if ((bool)e.NewValue)
        {

            InlineUIContainer container;
            if (_collapseButtonDictionary.ContainsKey(p))
            {
                container = _collapseButtonDictionary[p];
            }
            else
            {
                ToggleButton button = new ToggleButton() { Tag = p, Content = "Hide" };
                container = new InlineUIContainer() { Child = button };
                _collapseButtonDictionary.Add(p, container);
                button.Click += new RoutedEventHandler(CollapseButton_Click);
            }
            if (p.Inlines.Count > 0)
            {
                p.Inlines.InsertBefore(p.Inlines.First(), container);
            }
            else
            {
                p.Inlines.Add(container);
            }
        }
        else
        {
            if (_collapseButtonDictionary.ContainsKey(p))
            {
                var container = _collapseButtonDictionary[p];
                var tb = container.Child as ToggleButton;
                if ((bool)tb.IsChecked) SetCollapsedState(false, p);
                p.Inlines.Remove(container);
                _collapseButtonDictionary.Remove(p);
            }
        }
    }

    private static void CollapseButton_Click(object sender, RoutedEventArgs e)
    {
        ToggleButton button = sender as ToggleButton;
        var p = button.Tag as Paragraph;
        SetCollapsedState((bool)button.IsChecked, p);
    }

    private static void SetCollapsedState(bool isCollapsed, Paragraph p)
    {
        InlineUIContainer buttonContainer = _collapseButtonDictionary[p];
        List<Inline> disabledInlines;
        if (_paragraphInlineStorage.ContainsKey(p))
        {
            disabledInlines = _paragraphInlineStorage[p];
        }
        else
        {
            disabledInlines = new List<Inline>();
            _paragraphInlineStorage.Add(p, disabledInlines);
        }
        if (isCollapsed)
        {
            foreach (var item in p.Inlines)
            {
                disabledInlines.Add(item);
            }
            p.Inlines.Clear();
            p.Inlines.Add(buttonContainer);
        }
        else
        {
            p.Inlines.Clear();
            foreach (var item in disabledInlines)
            {
                p.Inlines.Add(item);
            }
            disabledInlines.Clear();
        }
    }
}
<Paragraph local:ParagraphExtensions.IsCollapsible="True">Lorem Ipsum</Paragraph>

实际上使段落可折叠可能不是最好的方法,我认为这种功能应该由面板/信封文档来处理。

This has to be one of the ugliest extensions ever (in terms of code and visuals) but it "makes a Paragraph collabsible" and the text is still selectable.

public static class ParagraphExtensions
{
    private static Dictionary<Paragraph, InlineUIContainer> _collapseButtonDictionary;
    private static Dictionary<Paragraph, List<Inline>> _paragraphInlineStorage;

    public static readonly DependencyProperty IsCollapsibleProperty =
        DependencyProperty.RegisterAttached("IsCollapsible", typeof(bool), typeof(Paragraph), new UIPropertyMetadata(false, IsCollapsibleChanged));
    public static bool GetIsCollapsible(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsCollapsibleProperty);
    }
    public static void SetIsCollapsible(DependencyObject obj, bool value)
    {
        obj.SetValue(IsCollapsibleProperty, value);
    }

    private static void IsCollapsibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        if (_collapseButtonDictionary == null) _collapseButtonDictionary = new Dictionary<Paragraph, InlineUIContainer>();
        if (_paragraphInlineStorage == null) _paragraphInlineStorage = new Dictionary<Paragraph, List<Inline>>();

        Paragraph p = sender as Paragraph;
        if ((bool)e.NewValue)
        {

            InlineUIContainer container;
            if (_collapseButtonDictionary.ContainsKey(p))
            {
                container = _collapseButtonDictionary[p];
            }
            else
            {
                ToggleButton button = new ToggleButton() { Tag = p, Content = "Hide" };
                container = new InlineUIContainer() { Child = button };
                _collapseButtonDictionary.Add(p, container);
                button.Click += new RoutedEventHandler(CollapseButton_Click);
            }
            if (p.Inlines.Count > 0)
            {
                p.Inlines.InsertBefore(p.Inlines.First(), container);
            }
            else
            {
                p.Inlines.Add(container);
            }
        }
        else
        {
            if (_collapseButtonDictionary.ContainsKey(p))
            {
                var container = _collapseButtonDictionary[p];
                var tb = container.Child as ToggleButton;
                if ((bool)tb.IsChecked) SetCollapsedState(false, p);
                p.Inlines.Remove(container);
                _collapseButtonDictionary.Remove(p);
            }
        }
    }

    private static void CollapseButton_Click(object sender, RoutedEventArgs e)
    {
        ToggleButton button = sender as ToggleButton;
        var p = button.Tag as Paragraph;
        SetCollapsedState((bool)button.IsChecked, p);
    }

    private static void SetCollapsedState(bool isCollapsed, Paragraph p)
    {
        InlineUIContainer buttonContainer = _collapseButtonDictionary[p];
        List<Inline> disabledInlines;
        if (_paragraphInlineStorage.ContainsKey(p))
        {
            disabledInlines = _paragraphInlineStorage[p];
        }
        else
        {
            disabledInlines = new List<Inline>();
            _paragraphInlineStorage.Add(p, disabledInlines);
        }
        if (isCollapsed)
        {
            foreach (var item in p.Inlines)
            {
                disabledInlines.Add(item);
            }
            p.Inlines.Clear();
            p.Inlines.Add(buttonContainer);
        }
        else
        {
            p.Inlines.Clear();
            foreach (var item in disabledInlines)
            {
                p.Inlines.Add(item);
            }
            disabledInlines.Clear();
        }
    }
}
<Paragraph local:ParagraphExtensions.IsCollapsible="True">Lorem Ipsum</Paragraph>

Litterally making the paragraph collapsible is probably not the best approach, i think this kind of functionality is rather something the panel/enveloping document should take care of.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文